前言
在WEB開發的過程中,中文亂碼是最爲常見的問題之一。之所以會出現中文亂碼的情況,主要原因是:前端使用POST或者GET方法傳遞的參數一般使用瀏覽器預先設置的編碼方式進行編碼,中文瀏覽器一般是使用UTF8或者GBK,英文的一般是ISO編碼;而瀏覽器編碼完成後發送給服務器,服務器進行解碼的解碼方式默認是使用ISO8859-1。這就造成了編碼和解碼方式不統一的,進而出現了中文亂碼的問題。
在下面,我將給出分別對POST、GET方法亂碼的解決方案
對POST方法和GET方法的簡介
POST方法和GET方法是前端將表單中的內容提交到服務器端的方法,二者有着很大的不同之處。
首先,GET方法是直接把表單中的內容直接放在了URL中進行傳值,就像這種:
可以很明顯的看到,使用這種方式進行傳參是對用戶可見的,這就有了一定的安全隱患,所以,一般這種方法都不會用在對安全性有要求的地方。
其次,POST方法就相對安很多了,POST方法會將參數放入HTTP請求報文的實體部分,對用戶來講是不可見的。
對於HTTP的介紹,我今後會寫一篇詳細的博客來爲大家講解,細數HTTP協議的相關內容,敬請期待。
解決方案
POST方法
對於POST方法,解決起來相對簡單。只需要在讀取參數之前設置一下解碼的的格式就行了。代碼示例如下:
public class LoginServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response){
//將解碼格式設置成UTF8
request.setCharacterEncoding("utf8");
String username = request.getParameter("username");
}
}
GET方法
而對於GET方法,就是比較麻煩的了。
第一種方案是,拿到所有的從前端傳遞過來的參數,進行統一編碼,然後是用正則表達式,字符串的split函數split(“&”)進行切割,切割完成後,再分別取出參數值。
//取出所有的參數
String allParameters = request.getQueryString();
//對參數重新編碼
String parameters = java.net.URLDecoder.decode(allParameters,"UTF-8");
//正則分割
String[] parameter = parameters.split("&");
第二種方案就更麻煩了。
首先要做的是獲取到請求的參數值,然後對這個參數值使用ISO-8859-1的格式分解成字節數組,然後再重新生成爲一個編碼格式是UTF8的字符串。
//獲取參數值
String name = request.getParameter("name");
//把參數值變成字節數組
byte[] nameBytes = name.getBytes("ISO-8859-1");
//生成新的編碼爲UTF8的字符串
String newName = new String(nameBytes,"UTF-8");
使用過濾器Filter
很明顯,如果我的服務端有着大量的Servlet,這樣的做法會造成大量的代碼重複,顯然是不滿足代碼複用的要求的,於是我們選擇使用過濾器,對請求進行過濾。
下面的這個文件是對兩種請求方式的編碼與解碼。
EncodingRequest.java
public class EncodingRequest extends HttpServletRequestWrapper {
private String charset;
public EncodingRequest(HttpServletRequest request, String charset) {
super(request);
this.charset = charset;
}
public String getParameter(String name) {
HttpServletRequest request = (HttpServletRequest) getRequest();
String method = request.getMethod();
if(method.equalsIgnoreCase("post")) {
try {
request.setCharacterEncoding(charset);
} catch (UnsupportedEncodingException e) {}
} else if(method.equalsIgnoreCase("get")) {
String value = request.getParameter(name);
try {
value = new String(name.getBytes("ISO-8859-1"), charset);
} catch (UnsupportedEncodingException e) {
}
return value;
}
return request.getParameter(name);
}
}
這個文件是過濾器,將所有請求都進行過濾。
public class EncodingFilter extends HttpFilter {
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String charset = this.getInitParameter("charset");
if(charset == null || charset.isEmpty()) {
charset = "UTF-8";
}
response.setCharacterEncoding(charset);
response.setContentType("text/html;charset=" + charset);
EncodingRequest res = new EncodingRequest(request, charset);
chain.doFilter(res, response);
}
}
最後,爲了讓過濾器工作,配置一下web.xml文件
<filter>
<filter-name>EncodingFilter</filter-name>
<!--包名及文件名-->
<filter-class>cn.roobtyan.filter.EncodingFilter</filter-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
做完如上工作,亂碼就解決了。
結語
感謝您的閱讀,歡迎指正博客中存在的問題,也可以跟我聯繫,一起進步,一起交流!
微信公衆號:進擊的程序狗
郵箱:[email protected]
個人博客:http://roobtyan.cn
掃描下面的二維碼關注我吧,你將收穫到意想不到的東西喲……
給大家準備了一份非常棒的JAVA的視頻教程,從JAVA基礎一直到JAVAWEB,還有非常強大的項目實戰。
就在我的微信公衆號裏,回覆java就可查看,免費的呦!