1.向客戶端發(fā)送數(shù)據 (重點是亂碼問題)
getOutputStream()
getWriter()
字節(jié)流發(fā)送數(shù)據的中文亂碼問題
服務器端指定了用utf-8來發(fā)送數(shù)據, 瀏覽器在接受數(shù)據時, 如果不指定將使用默認的平臺碼GBK, 編解碼不一致導致亂碼.
解決方案:
response.setHeader("Content-Type", "text/html;charset=utf-8");// 通知瀏覽器使用utf-8打開服務器發(fā)送過去的數(shù)據
response.getOutputStream().write("中國".getBytes("utf-8"));// 指定編碼為utf-8
字符流發(fā)送數(shù)據的中文亂碼問題
利用字符流發(fā)送數(shù)據, 底層還是要轉成字節(jié). 服務器端如果不手動指定, 服務器默認會使用iso8859-1碼表, 由于里面沒有中文漢字, 所以服務器端發(fā)送給客戶端就是一堆亂碼, 客戶端不管使用什么碼表都無法轉成正常的字符
服務器會根據getCharacterEncoding()方法返回的編碼來發(fā)送數(shù)據, 如果沒有指定, 該方法默認返回iso8859-1
解決方案:
第一步, 需要指定服務器發(fā)送數(shù)據使用utf-8
response.setCharacterEncoding("utf-8"); //通知服務器使用utf-8來發(fā)送響應實體中數(shù)據
第二步: 需要指定瀏覽器在接收數(shù)據時也使用同一個編碼來打開數(shù)據
response.setHeader("Content-Type", "text/html;charset=utf-8");
等價于<==>
response.setContentType("text/html;charset=utf-8");
在通知瀏覽器使用什么編碼接受服務器發(fā)送的數(shù)據時, 服務器很智能, 會使用相同的編碼來發(fā)送數(shù)據, 所以指定服務器以什么編碼發(fā)送數(shù)據的代碼可以省略不寫
總結: 不管是字符流還是字節(jié)流, 解決亂碼問題, 可以用一行代碼搞定:
response.setContentType("text/html;charset=xxx");
getOutputStream()和getWriter() 這兩個方法是互斥的, 在一次請求當中調用了其中的一個, 就不能再調用另一個!!!
在調用完getOutputStream()或getWriter()方法之后, 不需要手動去關閉流, 服務器會自動幫我們去關閉!!!
這個兩個方法獲取到的流并不是指向客戶端的流, 而是指向response緩沖區(qū)的流, 通過流將數(shù)據寫入response緩沖區(qū), service方法執(zhí)行結束, 請求回到服務器, 由服務器將數(shù)據組織成響應消息打給瀏覽器!!
2.實現(xiàn)重定向
重定向的原理就是302+location, 通過設置狀態(tài)碼302和location響應頭就可以實現(xiàn)重定向的效果
response.setStatus(302);
response.setHeader("Location", "/Day09/index.jsp");
這兩行代碼等價于
response.sendRedirect("/Day09/index.jsp");
3.實現(xiàn)定時刷新
定時刷新是通過Refresh響應頭, 可以實現(xiàn)在多少秒之后跳轉到另外一個資源
response.setHeader("Refresh", "3;url=/Day09/index.jsp");
總結:
請求轉發(fā)/請求重定向/定時刷新都可以實現(xiàn)資源的跳轉, 區(qū)別是什么呢?**
請求轉發(fā):
一次請求,一次響應 request對象是同一個
地址欄不會發(fā)生變化
只能用于服務器內部的資源跳轉, 并且只能是同一應用中的不同資源上進行跳轉, 不可用在不同應用和不同服務器中的資源跳轉
請求重定向:
兩次請求,兩次響應 request對象不是同一個
地址欄會發(fā)生變化
可以用于服務器內部的資源跳轉, 也可以用于不同應用和不同服務器之間的資源跳轉
定時刷新:
兩次請求,兩次響應 request對象不是同一個
地址欄會發(fā)生變化
可以用于服務器內部的資源跳轉, 也可以用于不同應用和不同服務器之間的資源跳轉
和重定向不同的是, 定時刷新可以在刷新到新的地址之間設置一個時間, 在間隔的這段時間內可以輸出文本到瀏覽器并維系一段時間
那什么時候用哪種方式進行資源的跳轉呢?
如果是同一服務器中的同一應用內部的資源跳轉:
~如果需要利用request域在跳轉的資源之間傳輸數(shù)據, 只能用請求轉發(fā)
~如果不想讓地址欄發(fā)生變化, 只能用請求轉發(fā)
~如果需要地址欄發(fā)生變化, 只能用重定向或定時刷新
~如果沒有什么特殊需求, 三種方式都可以, 但是推薦使用轉發(fā), 可以減少請求次數(shù)降低服務器的壓力.
~如果只是想更新刷新操作, 最好使用重定向或定時刷新, 使用請求轉發(fā), 在刷新時會把剛才的操作再做一遍, 可能會導致一些問題, 比如表單重復提交或重復支付訂單等
如果是不同服務器或不同應用內部的資源跳轉, 只能用重定向或這定時刷新:
重定向和定時刷新的主要區(qū)別在于: 重定向會立即跳轉, 而定時刷新可以設置一個時間間隔, 在指定時間后再進行跳轉.
如果在跳轉之前需要輸出提示信息(如: 注冊成功, xx秒后跳轉到xxx)只能用定時刷新, 否則兩種方式都可以.
4.控制瀏覽器的緩存行為 (!掌握)
由于不同的瀏覽器的緩存行為可能是不同的, 我們可以在服務器中通過設置響應頭來控制瀏覽器的緩存行為!!
控制瀏覽器不要緩存:
setDateHeader("Expires", -1);
setHeader("Cache-control", "no-cache");
setHeader("Pragma", "no-cache");
控制瀏覽器緩存:
setDateHeader("Expires", System.currentTimeMillis()+10006060*24);
setHeader("Cache-control", "max-age=60");
附:
HTTP1.1 響應碼 -- 一個3位的數(shù)字, 范圍為100~600, 表示服務器處理請求的結果
200~299 表示服務器正確的處理了請求
300~399 表示服務器正確的處理了本次請求, 但是如果想要繼續(xù)執(zhí)行, 還需要更多的額外信息
400~499 表示客戶端的請求有問題
500~599 表示服務器端發(fā)生了問題
200 表示服務器處理成功
302 表示請求重定向
304/307 通知瀏覽器使用緩存資源
404 表示客戶端請求的資源不存在
500 表示服務器端處理請求出錯