一、編碼亂碼
-
英文
無論是Unicode還是GBK,英文編碼都是一致的 -
中文
不同字符集間編碼不一致,甚至是表示一個字符的字節數都不一致,所以就會出現很多的亂碼問題。 -
程序中
強力推薦使用UTF-8編碼
1、常見中文編碼及字節數
GBK(兩個字節)
GB_2312(兩個字節)
Unicode(四個字節)
UTF-8(三個字節)
不同編碼不但佔用的字節數不同,字節編碼也不相同!
程序世界能不用中文就不用中文,只能出現在兩個地方:註釋和字符串
2、爲什麼不用一個字節表示一個漢字
因爲漢字太多了,表示不過來,一個字節表示的範圍是0~255,最多能表示256個字符。光是常用的就有2000多個,所以一個字節存儲不過來。
英文編碼呢,比如LATIN_1字符集,一個字節(256個字符)可以表示西歐國家的文字的字符集,不存在亂碼問題
3、編碼之間的瓜葛
一個字節表示漢字不夠,那如果使用兩個字節表示漢字呢?
兩個字節0~65535,存儲漢字夠了(5萬多個)
那爲什麼UTF-8編碼要3個字節,unicode編碼使用4個字節,GBK使用2個字節,爲什麼不統一
其實最早出現的中文編碼是GBK和GB2312字符集,是中國人自己制定的漢字編碼,佔用兩個字節。Windows是全世界使用最多的PC操作系統,是最早研發中文操作系統的,由於歷史原因,一直延續使用的是GBK字符集。
後來,國際化標準組織想要發明一個能夠表示世界上所有國家語言文字的字符集(Unicode組織),就有了UTF-8和Unicode編碼。UTF-8中一箇中文字符佔用三個字節,而Unicode編碼是可變長度的(1~4個字節,一般是4個字節),使用頻率越高的佔用的字節越少,使用頻率越低的語言,佔用的字節越多。
Unicode字符集僅僅是字符的表示編碼,並未規定表示編碼如何存儲到計算機中,由此引出了UTF-8編碼。UTF-8是Unicode編碼在計算機中的存儲編碼,UTF-8編碼中,一個漢字佔用3個字節,一個英文一個字節。
我們在程序中程序中儘量使用UTF-8編碼,Windows默認的是GBK編碼,程序中能不出現中文就儘量不要使用中文,中文只允許出現在註釋和字符串中,養成良好的編程習慣
4、Servlet亂碼問題解決方案
- request.setCharacterEncoding(“UTF-8”)修改,不推薦,每次都要設置,太麻煩
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
- 使用過濾器,推薦,一勞永逸
package org.westos.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;
//凡是過濾器,value = "/*",過濾所有的
@WebFilter(description = "EncodingFilter", value = "/*", initParams = {@WebInitParam(name = "encoding", value = "UTF-8")})
public class EncodingFilter implements Filter {
private String encoding;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.encoding =filterConfig.getInitParameter("encoding");
}
//過濾器在過濾請求的時候,一定會執行doFilter方法,將請求和響應的字符集都設置爲UTF-8
//過濾器過濾的是請求
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//給請求和響應設置爲UTF-8編碼
servletRequest.setCharacterEncoding(this.encoding);
servletResponse.setCharacterEncoding(this.encoding);
//過濾器鏈條,確保繼續向後過濾
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
- 也可以在xml配置文件中進行配置