posts - 0,  comments - 6,  trackbacks - 0

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

          tomcat下,我們通常這樣來解決中文亂碼問題:

           

          過濾器代碼:

          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中過濾器配置:

          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按照已經設置的字符編碼來進行字符輸出。

           

          通過過濾器,我們可以保證在Servlet或JSP執行之前就設置好了請求和響應的字符編碼。

           

          但是這樣并不能完全解決中文亂碼問題:

          對于post請求,無論是“獲取參數環節”還是“輸出環節"都是沒問題的;

          對于get請求,"輸出環節"沒有問題,但是"獲取參數環節"依然出現中文亂碼,所以在輸出時直接將亂碼輸出了。

           

          原因是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方法來獲取參數,就已經完成了字符編碼的轉換過程,我們就不需要在每次獲取參數時來進行字符編碼轉換了。


          其實用動態代理來實現可能更好,這里只是我講課時的一個例子,用來介紹HttpServletRequestWrapper,不對之處,敬請指教,以免誤人子弟啊。


          源代碼示例工程:http://www.aygfsteel.com/Files/whistler/demo.rar


          學軟件開發,到蜂鳥科技!
          超強的師資力量 、完善的課程體系 、超低的培訓價格 、真實的企業項目。

          網址:www.ntcsoft.com 
          電話:0371-63839606 
          鄭州軟件開發興趣小組群:38236716

           

          posted on 2010-11-26 01:08 whistler 閱讀(983) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          留言簿(2)

          我參與的團隊

          文章檔案(22)

          搜索

          •  

          最新評論

          主站蜘蛛池模板: 绥中县| 鹤岗市| 无极县| 依安县| 南部县| 浦江县| 嵊泗县| 安顺市| 杭锦旗| 长丰县| 揭东县| 乌苏市| 鹤岗市| 临西县| 乾安县| 乡宁县| 西乌珠穆沁旗| 深水埗区| 邯郸市| 班玛县| 宾川县| 威远县| 武汉市| 广饶县| 本溪市| 大厂| 张家界市| 宝清县| 越西县| 张北县| 封开县| 门头沟区| 新密市| 聂拉木县| 讷河市| 陆川县| 沐川县| 吴忠市| 博湖县| 山西省| 巍山|