一、Response發送數據時可能導致亂碼:
1、Response.getOutputStream().write("中國".getBytes()) ;
這里默認用平臺字節碼進行編碼,發送給瀏覽器(瀏覽器默認的也 是用平臺字節碼進行編碼)。如果瀏覽器不是使用默認的編碼格式(如果使用 utf-8),那么在輸出數據時也要選擇要使用的編碼格式進行編碼:
response.getOutputStream().write("中國".getBytes("utf-8")) ;
2、response.getWriter().write("中國");
這里默認使用iso-8859-1 編碼集進行編碼,所以使用該方法最容易 導致亂碼,在使用字符流輸出數據時,要在獲取字符流對象前手動進行編碼 設置: response.setContentType("text/html;Charset=utf-8") ; 或者: response.setCharacterEncoding("gbk") ;
|——注意:使用response.setCharacterEncoding("gbk") ;時 設置的編碼格式和系統默認的則只需要上述一條語句。
否則還要加上: response.setCharacterEncoding("utf-8") ;
response.setHeader("Content-Type", "text/html;Charset=utf-8");
所以:為了方便一般設置:response.setContentType("text/html;Charset=utf-8") ;即可
二、Request 獲取請求參數時可能導致亂碼:
瀏覽器發送的請求參數使用的編碼就是打開網頁時使用的編碼,而服 務器獲取發送過來的請求參數默認使用 ISO-8859-1 進行解碼操作,所以這過 程中可能導致亂碼:
1、對于Post方式提交的數據:
可以設置request.setCharacterEncoding("utf-8");來明確指定獲取 參數時使用的編碼,但是此種方法只對Post 方式提交的數據有用;即是只對 請求體有用。
2、對于Get方法提交的數據:
只能手動解決亂碼: String str = new String(name.getBytes("ISO8859-1"),"gbk") ;
3、通過配置tomcat的servlet.xml 配置:
在tomcat的server.xml中可以配置http連接器的URIEncoding可以指定 服務器在獲取請求參數時默認使用的編碼,從而一勞永逸的決絕獲取請求參數時 的亂碼問題。也可以指定useBodyEncodingForURI參數,令request.setCharacterEncoding也 對GET方式的請求起作用,但是這倆屬性都不推薦使用,因為發布環境往往不允許修改此屬性。
三、URL中包含中文時可能出現亂碼:
解決方法URL編碼:
1、由于HTTP協議規定,URL路徑只能存在ASCLL碼中的字符,所以如果URL中存在中文或特殊字符需要進行URL編碼。
2、編碼原理:
將空格轉換為加號(+)
對0-9,a-z,A-Z之間的字符保持不變
對于所有其他的字符,用這個字符的當前字符集編碼在內存中的十六進制格式表示,并在每個字節前加上一個百分號(%)。如字符“+”用%2B表示,字符“=”用%3D表示,字符“&”用%26表示,每個中文字符在內存中占兩個字節,字符“中”用%D6%D0表示,字符“國”用%B9%FA表示調對于空格也可以直接使用其十六進制編碼方式,即用%20表示,而不是將它轉換成加號(+)
說明:
如果確信URL串的特殊字符沒有引起使用上的岐義或沖突你也可以對這些字符不進行編碼,而是直接傳遞給服務器。例如,http://jbelial.cnblogs.com?name=中國&password=123
如果URL串中的特殊字符可能會產生岐義或沖突,則必須對這些特殊字符進行URL編碼。
例如,服務器會將不編碼的“中+國”當作“中國”處理。還例如,當name參數值為“中&國”時,如果不對其中的“&”編碼,URL字符串將有如下形式:http://jbelial.cnblogs.com?name=中&國&password=123,應編碼為:http://jbelial.cnblogs.com?name=中%26國&password=123 http://jbelial.cnblogs.com/index.html#section2可改寫成http://jbelial.cnblogs.com%2Findex.html%23section2
3、在Java中進行URL編碼和解碼: URLencoder.encode("中文","utf-8") ; URLDecoder.decode(str,"utf-8") ;
四、JSTL : c:redircet 標簽內的 c:param 標簽自動編碼后,在重定向頁面要進行手動解碼。
五、在往數據庫存入數據時,往外里面存儲數據會出現亂碼:
mysql > show variables like 'charact%' ;
+--------------------------+---------------------------------------------------------+
| Variable_name | Value |
+--------------------------+---------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | C:\Program Files\MySQL\MySQL Server 5.0\share\charsets\ |
+--------------------------+---------------------------------------------------------+
原因:在安裝數據庫時,我們選擇的是默認為utf-8 編碼集;所以,數據庫服務器,默認我們寫入數據時即客戶端也是用的utf-8 編碼集;所以當客戶端gbk進行編碼,而服務器則以utf-8編碼進行解碼,所以會出現亂碼。
解決辦法:
1、set names 當前客戶端編碼集;
2、主要是解決:character_set_client ,character_set_connection 該兩個字段名的值。
set character_set_client gbk ;
set character_set_connection gbk ;
character_set_results 則是設置dos端顯示的編碼集。
-------------------------------------------------------------------------------更新時間:2013年7月11日 19:25:57
六、對全站中文亂碼問題的解決辦法——Filter
1 import java.io.IOException; 2 3 import javax.servlet.Filter; 4 import javax.servlet.FilterChain; 5 import javax.servlet.FilterConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 /**12 * 全站同一編碼13 * @author 賀佐安14 *15 */16 public class SetCharacterEncoding implements Filter {17 private FilterConfig filterConfig = null ;18 //獲取初始化的FilterConfig對象19 public void init(FilterConfig filterConfig) throws ServletException {20 this.filterConfig = filterConfig ;21 }22 23 public void doFilter(ServletRequest req , ServletResponse resp ,24 FilterChain chain) throws IOException, ServletException {25 HttpServletRequest request = (HttpServletRequest) req ; 26 HttpServletResponse response = (HttpServletResponse) resp ;27 28 //獲取初始化的字符編碼29 String encoding = filterConfig.getInitParameter("Encoding") ;30 request.setCharacterEncoding(encoding) ;31 response.setCharacterEncoding(encoding) ; 32 response.setContentType("text/html;charset="+encoding) ;33 34 MyHttpServletRequest myRequest = new MyHttpServletRequest(request) ;35 chain.doFilter(myRequest, response) ;36 }37 38 public void destroy() {39 40 }41 }
在設置同一編碼時,不要把編碼寫死,寫在配置文件中。當然,要用Filter 進行過濾的話要對HttpServletRequest 接口進行包裝:目的是解決get方式提交也不會出現亂碼問題。
代碼如下:
1 import java.io.UnsupportedEncodingException; 2 3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletRequestWrapper; 5 /** 6 * 包裝HttpServletRequest 類,為了解決全站亂碼問題 7 * @author 賀佐安 8 * 9 */10 public class MyHttpServletRequest extends HttpServletRequestWrapper {11 public MyHttpServletRequest (HttpServletRequest request) {12 super(request) ;13 }14 15 //對getParameter方法進行修飾: 主要是為了解決用戶使用get方式提交的情況16 public String getParameter(String name) {17 //如果是get方法則手動解碼18 if("get".equalsIgnoreCase(super.getMethod())) {19 String value = super.getParameter(name) ;20 try {21 return new String (value.getBytes("ISO-8859-1"),super.getCharacterEncoding()) ;22 } catch (UnsupportedEncodingException e) {23 e.printStackTrace();24 }25 }26 return super.getParameter(name);27 }28 }
當然還要不要忘記配置web.xml:
1 <!-- 全站中文亂碼過濾器:開始 --> 2 <filter> 3 <filter-name>SetCharacterEncoding</filter-name> 4 <filter-class>filter.SetCharacterEncoding</filter-class> 5 <!-- 設置全站的編碼--> 6 <init-param> 7 <param-name>Encoding</param-name> 8 <param-value>UTF-8</param-value> 9 </init-param>10 </filter>11 <filter-mapping>12 <filter-name>SetCharacterEncoding</filter-name> 13 <url-pattern>/*</url-pattern>14 </filter-mapping>15 <!-- 全站中文亂碼過濾器:結束 -->