1. 程式人生 > >請求亂碼、響應亂碼的解決方案

請求亂碼、響應亂碼的解決方案

請求亂碼

客戶端傳送請求常用方式是GET、POST

GET請求

  1. 使用程式碼轉換的方式
  2. 修改tomcat配置檔案server.xml的方式

程式碼轉換

url

http://localhost:8080/HelloServlet/h5?username=王學武

servlet類

 1 public class HelloServlet5 extends HttpServlet {
 2 
 3     @Override
 4     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException { 5 String username = req.getParameter("username"); 6 //get請求過來的資料,在url位址列上就已經經過編碼了,所以我們取到的就是亂碼 7 System.out.println("username===" + username); 8 9 //tomcat收到了這批資料,getParameter 預設使用ISO-8859-1去解碼 10 //先讓文字回到ISO-8859-1對應的位元組陣列 , 然後再按utf-8組拼字串
11 username = new String(username.getBytes("ISO-8859-1"), "UTF-8"); 12 System.out.println("username===" + username); 13 } 14 15 }

console輸出

username===王学武
username===王學武 

修改tomcat配置檔案

直接在tomcat裡面做配置,在tomcat裡面做設定處理 conf/server.xml 加上URIEncoding="utf-8",以後get請求過來的資料永遠都是用UTF-8編碼

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="utf-8"/>

servlet類

1 public class HelloServlet5 extends HttpServlet {
2     @Override
3     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
4         String username = req.getParameter("username");
5         System.out.println("username===" + username);
6     }
7 }

console輸出

username===王學武

POST請求

設定請求體裡面的文字編碼

request.setCharacterEncoding("UTF-8");

servlet類

 1 public class HelloServlet5 extends HttpServlet {
 2 
 3     @Override
 4     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 5         req.setCharacterEncoding("utf-8");
 6         String name = req.getParameter("username");
 7         System.out.println("設定請求體編碼後:name==="+name);
 8     }
 9     
10 }

console輸出

設定請求體編碼後:name===王五

如果在獲取引數後設置req.setCharacterEncoding("utf-8");就不會起作用

 1 public class HelloServlet5 extends HttpServlet {
 2 
 3     @Override
 4     protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 5         String name = req.getParameter("username");
 6         System.out.println("設定請求體編碼前:name==="+name);
 7         System.out.println("-------------------------");
 8         
 9         req.setCharacterEncoding("utf-8");
10         name = req.getParameter("username");
11         System.out.println("設定請求體編碼後:name==="+name);
12     }
13     
14 }

console輸出

設定請求體編碼前:name===王五
-------------------------
設定請求體編碼後:name===王äº 

對GET方式不起作用

 url

http://localhost:8080/HelloServlet/h5?name=王學武

servlet類

 1 public class HelloServlet5 extends HttpServlet {
 2 
 3     @Override
 4     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 5         req.setCharacterEncoding("utf-8");
 6         String name = req.getParameter("name");
 7         System.out.println("name==="+name);
 8     }
 9     
10 }

console輸出

name===王学武 

響應亂碼

響應輸出有兩種方式

  1. 字元流
  2. 位元組流

 

 1 public class HelloServlet5 extends HttpServlet {
 2 
 3     @Override
 4     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 5         //以字元流的方式寫資料
 6 //        resp.getWriter().write("<h3>response...</h3><br/>");
 7 //        resp.getWriter().write("<h3>response...</h3>");
 8 //        resp.getWriter().flush();
 9         //以位元組流的方式寫資料
10         resp.getOutputStream().write("response...".getBytes());
11     }
12     
13 }

注:getWriter(),outPutStream在進行檔案寫入操作只能用一個,否則會丟擲java.lang.IllegalStateException: getWriter() has already been called for this response

 字元流輸出亂碼

 1 public class HelloServlet5 extends HttpServlet {
 2 
 3     @Override
 4     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 5         //以字元流的方式寫資料
 6         PrintWriter out = resp.getWriter();
 7         //out.write("<h3>響應輸出資料</h3><br/>");
 8         
 9         //1. 指定輸出到客戶端的時候,這些文字使用UTF-8編碼
10         resp.setCharacterEncoding("UTF-8");
11         //2. 直接規定瀏覽器看這份資料的時候,使用什麼編碼來看。
12         resp.setHeader("Content-Type", "text/html; charset=UTF-8");
13         
14         out.write("<h3>響應輸出資料</h3>");
15     }
16     
17 }

 

原因:必須在resp.getWriter()之前設定字元編碼操作

 1 public class HelloServlet5 extends HttpServlet {
 2 
 3     @Override
 4     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 5         
 6         //1. 指定輸出到客戶端的時候,這些文字使用UTF-8編碼
 7         resp.setCharacterEncoding("UTF-8");
 8         //2. 直接規定瀏覽器看這份資料的時候,使用什麼編碼來看。
 9         resp.setHeader("Content-Type", "text/html; charset=UTF-8");
10         
11         //以字元流的方式寫資料
12         PrintWriter out = resp.getWriter();
13         out.write("<h3>響應輸出資料</h3>");
14     }
15     
16 }

 

 修改servlet類的程式碼

 1 public class HelloServlet5 extends HttpServlet {
 2 
 3     @Override
 4     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 5         
 6         //1. 指定輸出到客戶端的時候,這些文字使用UTF-8編碼
 7         resp.setCharacterEncoding("UTF-8");
 8         //2. 直接規定瀏覽器看這份資料的時候,使用什麼編碼來看。
 9         resp.setHeader("Content-Type", "text/html; charset=UTF-8");
10         
11         //以字元流的方式寫資料
12         PrintWriter out = resp.getWriter();
13         out.write("<h3>響應輸出資料</h3>");
14     }
15     
16 }

位元組流輸出

 1 public class HelloServlet5 extends HttpServlet {
 2     @Override
 3     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 4         //1. 指定瀏覽器看這份資料使用的碼錶
 5         resp.setHeader("Content-Type", "text/html;charset=UTF-8");
 6         
 7         //2. 指定輸出的中文用的碼錶
 8         resp.getOutputStream().write("響應輸出資料".getBytes("UTF-8"));
 9     }
10 }

其實,無論是位元組流輸出還是字元流輸出,通用寫法:

  1. response.setContentType("text/html;charset=UTF-8")
  2. 寫輸出資料即可