request和response的中文亂碼問題及解決方案

request亂碼指的是:瀏覽器向服務器發送的請求參數中包含中文字符,服務器獲取到的請求參數的值是亂碼;

response亂碼指的是:服務器向瀏覽器發送的數據包含中文字符,瀏覽器中顯示的是亂碼;


一、亂碼產生的原因

不管是request亂碼還是response亂碼,其實都是由於客戶端(瀏覽器)跟服務器端採用的編碼格式不一致造成的。


以request亂碼爲例:瀏覽器向服務器發送請求,因爲瀏覽器與服務器之間的通信實質上是socket流,所以要先將請求參數(字符)轉換成字節,也就是編碼過程,服務器接收到請求參數後進行解碼(字節轉字符),然後封裝到request對象中。如果客戶端的編碼與服務器端的解碼不統一,就會導致通過request獲取到的請求參數的值是亂碼。


二、亂碼分類及解決方案

(一)、response亂碼

服務器發給瀏覽器的數據默認是按照ISO-8859-1編碼,瀏覽器接收到數據後按照默認的字符集進行解碼後顯示,如果瀏覽器的默認解碼字符集不是ISO-8859-1,就出現亂碼。

對於response亂碼,只需要在服務器端指定一個編碼字符集,然後通知瀏覽器按照這個字符集進行解碼就可以了。
有三種方式:
1、response.setCharacterEncoding("utf-8”);//設置服務器端的編碼,默認是ISO-8859-1;該方法必須在response.getWriter()之前進行設置
response.setHeader("contentType", "text/html; charset=utf-8”);//通知瀏覽器服務器發送的數據格式是text/html,並要求瀏覽器使用utf-8進行解碼。

2、response.setContentType("text/html;charset=utf-8”);//等同於response.setHeader("contentType", "text/html; charset=utf-8”);
而且,它會覆蓋response.setCharacterEncoding("utf-8”) ,
在開發中只需要設置response.setContentType("text/html;charset=utf-8”)就可以了。意思是通知瀏覽器服務器發送的數據格式是text/html,服務器採用utf-8編碼,並要求瀏覽器使用utf-8進行解碼。

3、response.setCharacterEncoding("utf-8”);//設置服務器端的編碼爲utf-8
      response.getWriter().println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>”);//要求瀏覽器使用utf-8進行解碼 

可以看出,第二種方式是最簡便的,這也是我們在開發中最常使用的方式。


(二)、request亂碼

從瀏覽器發起的訪問方式有三種:在地址欄直接輸入URL訪問、點擊頁面中的超鏈接訪問、提交表單訪問。


在服務器端,通過request.setCharacterEncoding("XXX”)即可設置服務器的解碼爲XXX(默認是ISO-8859-1)。
只要服務器的解碼字符集和請求參數的編碼字符集一致,就不會產生亂碼】


1、post方式:表單提交

post方式屬於表單提交,參數存在於請求體
其編碼方式和  <%@ page language="java" contentType="text/html;charset=UTF-8"
pageEncoding="GBK%>  中的charset=UTF-8的編碼方式一致。
通過request.setCharacterEncoding("UTF-8”)即可解決亂碼。


2、get方式:超鏈接、在地址欄輸入URL

get方式提交的參數會跟在請求行中的uri後邊,服務器按照默認的iso-8859-1進行解碼(注意:是服務器對URI參數進行編碼,且一律採用ISO8859-1進行解碼)
這時候解決亂碼有兩種辦法:


·辦法一:修改服務器端對uri參數的默認編碼


在tomcat的server.xml中,
(1)設置<Connector ….>元素的屬性URIEncoding="UTF-8”即可。(默認沒有設置此屬性),指定URI使用“UTF-8”編碼方式。
注意:其要求 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="GBK" %> 中的charset的值爲UTF-8,否則依舊亂碼。
【例如:<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" URIEncoding="UTF-8”/>】


(2)設置<Connector ….>元素的屬性useBodyEncodingForURI=“true”,(默認沒有設置此屬性),意思是URI使用和請求體一樣的編碼方式,以請求體的爲準。
即URI和  <%@ page language="java" contentType="text/html; charset=XXX"
pageEncoding="GBK" %>  中的charset=XXX的編碼方式一致。(可以是GBK,也可以是UTF-8)
【例如:<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"useBodyEncodingForURI=“true”/>】

注意:同時設置這兩個屬性(URIEncoding="UTF-8” 與 useBodyEncodingForURI=“true”),則URI還是使用和請求體一樣的編碼方式,useBodyEncodingForURI=“true”有效,URIEncoding="UTF-8”無效。


一步到位

1、通過修改server.xml指定服務器對get和post統一按照utf-8解碼,即同時設置(URIEncoding="UTF-8” 與 useBodyEncodingForURI=“true”)
2、要求tomcat管理下的所有web應用都要使用utf-8編碼,即所有的jsp、html頁面都使用utf-8編碼。
比如 JSP頁面的頭信息是這樣的:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"]]>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"]]>
<title>Insert title here</title>
</head>
3、在Servlet的doGet和doPost方法中:
通過 request.setCharacterEncoding("UTF-8"); 這行代碼,
告訴服務器,使用“UTF-8”編碼字符集,對請求參數進行解碼。

這樣,應該就不會出現request和response的中文亂碼問題了。

·辦法二:回退重編

根據ISO-8859-1進行回退
1、超鏈接:根據 <%@ page language="java" contentType="text/html;charset=XXX" pageEncoding="XXX"%> 中的charset的值 進行重編,即可得到正常的參數值。

2、在地址欄直接輸入URL:根據UTF-8進行重編。

例如:
<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
String name = request.getParameter("name”);//得到亂碼
name = new String(name.getBytes("iso-8859-1"),"utf-8”);//得到正常的name值
注意:name.getBytes();如果不指定編碼,默認按照gb2312進行編碼。

發佈了39 篇原創文章 · 獲贊 52 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章