筆記

          way

          HttpServletRequestWrapper相關

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

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

          過濾器代碼:

          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和其他地方也可能需要使用-->
           <context-param>
             <param-name>charset</param-name>
             <param-value>UTF-8</param-value>
           </context-param>

           <filter>
            <filter-name>ContentTypeFilter</filter-name>
            <filter-class>filter.ContentTypeFilter</filter-class>
           </filter>

           <filter-mapping>
            <filter-name>ContentTypeFilter</filter-name>
            <url-pattern>/*</url-pattern>
           </filter-mapping>

          equest.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字段中的參數不起作用,我們通常通過下面的代碼來完成編碼轉換:

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

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

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

              <Connector port="8080" protocol="HTTP/1.1"
                         connectionTimeout="20000"
                         redirectPort="8443"
                         URIEncoding="UTF-8"
               />

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

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

           

          package wrapper;

          import java.io.UnsupportedEncodingException;
          import java.net.URLDecoder;

          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletRequestWrapper;

          public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper {

              
          private String charset = "UTF-8";

              
          public GetHttpServletRequestWrapper(HttpServletRequest request) {
                  
          super(request);
              }


              
          /**
               * 獲得被裝飾對象的引用和采用的字符編碼
               * 
               * 
          @param request
               * 
          @param charset
               
          */

              
          public GetHttpServletRequestWrapper(HttpServletRequest request,
                      String charset) 
          {
                  
          super(request);
                  
          this.charset = charset;
              }


              
          /**
               * 實際上就是調用被包裝的請求對象的getParameter方法獲得參數,然后再進行編碼轉換
               
          */

              
          public String getParameter(String name) {
                  String value 
          = super.getParameter(name);
                  value 
          = value == null ? null : convert(value);
                  
          return value;
              }


              
          public String convert(String target) {
                  System.out.println(
          "編碼轉換之前:" + target);
                  
          try {
                      
          return new String(target.trim().getBytes("ISO-8859-1"), charset);
                  }
           catch (UnsupportedEncodingException e) {
                      
          return target;
                  }

              }

          }


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

              public void doFilter(ServletRequest request, ServletResponse response,
                      FilterChain chain) 
          throws IOException, ServletException {
                  
          // 設置請求響應字符編碼
                  request.setCharacterEncoding(charset);
                  response.setCharacterEncoding(charset);
                  
          // 新增加的代碼
                  HttpServletRequest req = (HttpServletRequest) request;

                  
          if (req.getMethod().equalsIgnoreCase("get")) {
                      req 
          = new GetHttpServletRequestWrapper(req, charset);
                  }


                  System.out.println(
          "----請求被" + config.getFilterName() + "過濾");
                  
          // 傳遞給目標servlet或jsp的實際上時包裝器對象的引用,而不是原始的HttpServletRequest對象
                  chain.doFilter(req, response);

                  System.out.println(
          "----響應被" + config.getFilterName() + "過濾");
              }

           

           

          這樣一來,在servlet中調用包裝器的getParameters方法來獲取參數,就已經完成了字符編碼的轉換過程,我們就不需要在每次獲取參數時來進行字符編碼轉換了。
          總結:自己寫類繼承HttpServletRequestWrapper,HttpServletRequestWrapper實現了HttpServletRequest接口。看tomcat的源代碼可以發現,ServletRequest作為一個Component ,ServletRequestWrapper作為一個比較標準的Decorator ,實現ServletRequest接口并把ServletRequest當作成員變量,其他繼承Decorator 的類(比如本例中的GetHttpServletRequestWrapper )就可以很好的操控ServletRequest及其子類(比如本例中的HttpServletRequest),HttpServletRequest的很多方法就可以根據我們的需求做改變,比如設置字符,去掉空格。
          參考:
          http://www.javaeye.com/topic/483158
          http://fishhappy365.javaeye.com/blog/484185
          http://www.javaeye.com/topic/220230

          posted on 2009-11-22 22:30 yuxh 閱讀(7205) 評論(0)  編輯  收藏 所屬分類: j2ee設計模式

          導航

          <2009年11月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          統計

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          收藏夾

          博客

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 和硕县| 安福县| 昌吉市| 当涂县| 墨江| 江川县| 孝感市| 张掖市| 东丽区| 登封市| 麻栗坡县| 上饶县| 萍乡市| 青岛市| 进贤县| 克山县| 塘沽区| 滦南县| 加查县| 永顺县| 茌平县| 瓦房店市| 高邑县| 黑水县| 芮城县| 西吉县| 湘潭县| 卢氏县| 股票| 蒲城县| 旌德县| 防城港市| 嫩江县| 桑植县| 江达县| 奉贤区| 集贤县| 鱼台县| 潍坊市| 通山县| 渑池县|