Web伺服器收到客戶端的http請求,會針對每個請求,分別建立一個用於代表請求的request對象,和代表回應的response對象。 request和response物件既然代表請求和回應,那我們要取得客戶機提交過來的數據,只需要找request物件就行了。要向客戶機輸出數據,只需要找response物件就行了。
複製代碼代碼如下:
package com.yyz.response;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//輸出中文的問題
public class ResponseDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String data = "中國";
OutputStream out = response.getOutputStream();
out.write(data.getBytes());
/**
* out.write(data.getBytes());這句程式碼涉及兩次查閱碼表。
* "中國"從字元資料變成位元組資料的時候,會查閱gb2312碼表。
* 資料傳送到瀏覽器端要顯示的時候,需要再次查閱碼表,這時查閱的碼表與瀏覽器的設定有關。
*/
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
瀏覽器編碼設定為GB2312時的測試結果:
瀏覽器編碼設定為UTF-8時的測試結果:
為了讓我們的網站能被國外用戶訪問,我們在將字元資料變成位元組資料時,要指定轉換的碼表為UTF-8。但這時如果瀏覽器以GB2312打開,又會出現亂碼問題。雖然可以透過改變瀏覽器的設定來解決這個亂碼問題,但不利於增強使用者體驗。因而我們需要用程式告訴瀏覽器查閱何種碼表顯示資料。
複製代碼代碼如下:
package com.yyz.response;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//輸出中文的問題
public class ResponseDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//在伺服器端,資料是以哪個碼表輸出的,那麼就要控制瀏覽器以哪個碼表開啟。
String data = "中國";
response.setHeader("content-type", "text/html;charset=UTF-8");
OutputStream out = response.getOutputStream();
out.write(data.getBytes("UTF-8"));
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
多學一招:
使用HTML語言裡面的<meta>標籤來控制瀏覽器行為。
<meta http-equiv="Content-type'' content=''text/html;charset=UTF-8">
http-equiv模擬了HTTP的回應頭,告訴瀏覽器以UTF-8的碼表開啟。真正的響應頭優先於用http-equiv模擬的響應頭。
實際開發中,伺服器向瀏覽器寫文字資料應該用字元流。但是透過response的getWriter方法拿到的字元流預設的碼表是ISO8859-1,這張碼表裡是沒有中文對應的編碼的,因而會把?對應的編碼發送給瀏覽器,瀏覽器打開後全是問號。透過response的setCharacterEncoding可以修改服務端傳送資料時查閱的碼表。
複製代碼代碼如下:
package com.yyz.response;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//輸出中文的問題
public class ResponseDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//在伺服器端,資料是以哪個碼表輸出的,那麼就要控制瀏覽器以哪個碼表開啟。
String data = "中國";
response.setHeader("content-type", "text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write(data);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);
}
}
這裡有幾個小細節要注意:
1. response.setCharacterEncoding("UTF-8");需要寫在PrintWriter out = response.getWriter();的前面。拿到字元流後再設定編碼是沒有用的。
2. response.setHeader("content-type", "text/html;charset=UTF-8");有一種更簡單的寫法response.setContentType("text/html;charset=UTF-8");。
3.response.setContentType("text/html;charset=UTF-8");這句程式碼其實有兩個作用:通知response以UTF-8輸出和瀏覽器以UTF-8開啟。即等價於response.setHeader("content-type", "text/html;charset=UTF-8");和response.setCharacterEncoding("UTF-8");兩句程式碼。
4.透過以上閱讀,讀者應該可以明白為什麼response.getOutputStream.write(1);這句程式碼在瀏覽器的輸出不是1。因為瀏覽器是文字編輯器,收到資料後會拿著1去查碼表,然後顯示對應字元。想在瀏覽器輸出數字,應該把數字變成字串,response.getOutputStream.write((1+"").getBytes());.
用OutputStream(位元組流)傳送資料:
1、response.getOutputStream().write(“中國”.getBytes());//以預設編碼發送數據
2、response.getOutputStream().write("中國".getBytes("UTF-8"));//以UTF-8編碼發送數據,瀏覽器(預設用GB2312)會出現亂碼
解決辦法:
2.1透過更改瀏覽器的編碼方式:IE/”查看”/”編碼”/”UTF-8”(不可取)
2.2透過設定回應頭告知客戶端編碼方式:response.setHeader(“Content-type”, “text/html;charset=UTF-8”);//告知瀏覽器資料類型及編碼
2.3透過meta標籤模擬請求頭:out.write("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />".getBytes());
2.4透過以下方法:response.setContentType("text/html;charset=UTF-8");