解決get方法傳遞URL參數中文亂碼問題

轉自:http://www.javaeye.com/topic/483158java

應用一:解決tomcat下中文亂碼問題(先來個簡單的) web

在tomcat下,咱們一般這樣來解決中文亂碼問題:tomcat

過濾器代碼:app

Java代碼  
  1. package filter;  
  2.   
  3. import java.io.*;  
  4. import javax.servlet.*;  
  5. import javax.servlet.http.*;  
  6. import wrapper.GetHttpServletRequestWrapper;  
  7.   
  8. public class ContentTypeFilter implements Filter {  
  9.   
  10.     private String charset = "UTF-8";  
  11.     private FilterConfig config;  
  12.       
  13.     public void destroy() {  
  14.         System.out.println(config.getFilterName()+"被銷燬");  
  15.         charset = null;  
  16.         config = null;  
  17.     }  
  18.   
  19.     public void doFilter(ServletRequest request, ServletResponse response,  
  20.             FilterChain chain) throws IOException, ServletException {  
  21.         //設置請求響應字符編碼  
  22.         request.setCharacterEncoding(charset);  
  23.         response.setCharacterEncoding(charset);  
  24.           
  25.         HttpServletRequest req = (HttpServletRequest)request;  
  26.           
  27.           
  28.         System.out.println("----請求被"+config.getFilterName()+"過濾");  
  29.         //執行下一個過濾器(若是有的話,不然執行目標servlet)  
  30.         chain.doFilter(req, response);  
  31.           
  32.         System.out.println("----響應被"+config.getFilterName()+"過濾");  
  33.   
  34.     }  
  35.   
  36.     public void init(FilterConfig config) throws ServletException {  
  37.             this.config = config;  
  38.             String charset = config.getServletContext().getInitParameter("charset");    
  39.             if( charset != null && charset.trim().length() != 0)  
  40.             {  
  41.                 this.charset = charset;  
  42.             }  
  43.     }  
  44.   
  45. }  

 

web.xml中過濾器配置:jsp

Xml代碼  
  1. <!--將採用的字符編碼配置成應用初始化參數而不是過濾器私有的初始化參數是由於在JSP和其餘地方也可能須要使用-->  
  2.     <context-param>  
  3.             <param-name>charset</param-name>  
  4.             <param-value>UTF-8</param-value>  
  5.     </context-param>  
  6.   
  7.     <filter>  
  8.         <filter-name>ContentTypeFilter</filter-name>  
  9.         <filter-class>filter.ContentTypeFilter</filter-class>  
  10.     </filter>  
  11.   
  12.     <filter-mapping>  
  13.         <filter-name>ContentTypeFilter</filter-name>  
  14.         <url-pattern>/*</url-pattern>  
  15.     </filter-mapping>  

request.setCharacterEncoding(charset); 必須寫在第一次使用request.getParameter()以前,這樣才能保證參數是按照已經設置的字符編碼來獲取。
response.setCharacterEncoding(charset);必須寫在PrintWriter out = request.getWriter()以前,這樣才能保證out按照已經設置的字符編碼來進行字符輸出。post

經過過濾器,咱們能夠保證在Servlet或JSP執行以前就設置好了請求和響應的字符編碼。this

可是這樣並不能徹底解決中文亂碼問題:編碼

對於post請求,不管是「獲取參數環節」仍是「輸出環節"都是沒問題的;url

對於get請求,"輸出環節"沒有問題,可是"獲取參數環節"依然出現中文亂碼,因此在輸出時直接將亂碼輸出了。spa

緣由是post請求和get請求存放參數位置是不一樣的:

post方式參數存放在請求數據包的消息體中。get方式參數存放在請求數據包的請求行的URI字段中,以?開始以param=value&parame2=value2的形式附加在URI字段以後。而request.setCharacterEncoding(charset); 只對消息體中的數據起做用,對於URI字段中的參數不起做用,咱們一般經過下面的代碼來完成編碼轉換:

Java代碼  
  1. String paramValue = request.getParameter("paramName");  
  2. paramValue = new String(paramValue.trim().getBytes("ISO-8859-1"), charset);  

可是每次進行這樣的轉換實在是很麻煩,有沒有統一的解決方案呢?

解決方案1: 在tomcat_home\conf\server.xml 中的Connector元素中設置URIEncoding屬性爲合適的字符編碼

Java代碼  
  1. <Connector port="8080" protocol="HTTP/1.1"   
  2.            connectionTimeout="20000"   
  3.            redirectPort="8443"   
  4.            URIEncoding="UTF-8"  
  5.  />  

這樣作的缺點是,同一個tomcat下的其餘應用也將受到影響。而其每次部署時都須要類修改配置也很麻煩。

解決方案2:自定義請求包裝器包裝請求,將字符編碼轉換的工做添加到getParameter()方法中

Java代碼  
  1. package wrapper;  
  2.   
  3. import java.io.UnsupportedEncodingException;  
  4. import java.net.URLDecoder;  
  5.   
  6. import javax.servlet.http.HttpServletRequest;  
  7. import javax.servlet.http.HttpServletRequestWrapper;  
  8.   
  9. public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {  
  10.   
  11.     private String charset = "UTF-8";  
  12.   
  13.     public GetHttpServletRequestWrapper(HttpServletRequest request) {  
  14.         super(request);  
  15.     }  
  16.   
  17.     /** 
  18.      * 得到被裝飾對象的引用和採用的字符編碼 
  19.      * @param request 
  20.      * @param charset 
  21.      */  
  22.     public GetHttpServletRequestWrapper(HttpServletRequest request,  
  23.             String charset) {  
  24.         super(request);  
  25.         this.charset = charset;  
  26.     }  
  27.   
  28.     /** 
  29.      * 實際上就是調用被包裝的請求對象的getParameter方法得到參數,而後再進行編碼轉換 
  30.      */  
  31.     public String getParameter(String name) {  
  32.         String value = super.getParameter(name);  
  33.         value = value == null ? null : convert(value);  
  34.         return value;  
  35.     }  
  36.   
  37.     public String convert(String target) {  
  38.         System.out.println("編碼轉換以前:" + target);  
  39.         try {  
  40.             return new String(target.trim().getBytes("ISO-8859-1"), charset);  
  41.         } catch (UnsupportedEncodingException e) {  
  42.             return target;  
  43.         }  
  44.     }  
  45.   
  46. }  

修改過濾器的doFilter方法 代碼以下:

Java代碼  
  1. public void doFilter(ServletRequest request, ServletResponse response,  
  2.             FilterChain chain) throws IOException, ServletException {  
  3.         //設置請求響應字符編碼  
  4.         request.setCharacterEncoding(charset);  
  5.         response.setCharacterEncoding(charset);  
  6.         //新增長的代碼          
  7.         HttpServletRequest req = (HttpServletRequest)request;  
  8.           
  9.         if(req.getMethod().equalsIgnoreCase("get"))  
  10.         {  
  11.             req = new GetHttpServletRequestWrapper(req,charset);  
  12.         }  
  13.           
  14.         System.out.println("----請求被"+config.getFilterName()+"過濾");  
  15.         //傳遞給目標servlet或jsp的實際上時包裝器對象的引用,而不是原始的HttpServletRequest對象  
  16.         chain.doFilter(req, response);  
  17.           
  18.         System.out.println("----響應被"+config.getFilterName()+"過濾");  
  19.   
  20.     }  

這樣一來,在servlet中調用包裝器的getParameters方法來獲取參數,就已經完成了字符編碼的轉換過程,咱們就不須要在每次獲取參數時來進行字符編碼轉換了。

相關文章
相關標籤/搜索