posts - 0,  comments - 6,  trackbacks - 0

          應(yīng)用一:解決tomcat下中文亂碼問題(先來個(gè)簡(jiǎn)單的) 

          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.         //設(shè)置請(qǐng)求響應(yīng)字符編碼  
          22.         request.setCharacterEncoding(charset);  
          23.         response.setCharacterEncoding(charset);  
          24.           
          25.         HttpServletRequest req = (HttpServletRequest)request;  
          26.           
          27.           
          28.         System.out.println("----請(qǐng)求被"+config.getFilterName()+"過濾");  
          29.         //執(zhí)行下一個(gè)過濾器(如果有的話,否則執(zhí)行目標(biāo)servlet)  
          30.         chain.doFilter(req, response);  
          31.           
          32.         System.out.println("----響應(yīng)被"+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. <!--將采用的字符編碼配置成應(yīng)用初始化參數(shù)而不是過濾器私有的初始化參數(shù)是因?yàn)樵贘SP和其他地方也可能需要使用-->  
          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()之前,這樣才能保證參數(shù)是按照已經(jīng)設(shè)置的字符編碼來獲取。
          response.setCharacterEncoding(charset);必須寫在PrintWriter out = request.getWriter()之前,這樣才能保證out按照已經(jīng)設(shè)置的字符編碼來進(jìn)行字符輸出。

           

          通過過濾器,我們可以保證在Servlet或JSP執(zhí)行之前就設(shè)置好了請(qǐng)求和響應(yīng)的字符編碼。

           

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

          對(duì)于post請(qǐng)求,無論是“獲取參數(shù)環(huán)節(jié)”還是“輸出環(huán)節(jié)"都是沒問題的;

          對(duì)于get請(qǐng)求,"輸出環(huán)節(jié)"沒有問題,但是"獲取參數(shù)環(huán)節(jié)"依然出現(xiàn)中文亂碼,所以在輸出時(shí)直接將亂碼輸出了。

           

          原因是post請(qǐng)求和get請(qǐng)求存放參數(shù)位置是不同的:

          post方式參數(shù)存放在請(qǐng)求數(shù)據(jù)包的消息體中。get方式參數(shù)存放在請(qǐng)求數(shù)據(jù)包的請(qǐng)求行的URI字段中,以?開始以param=value&parame2=value2的形式附加在URI字段之后。而request.setCharacterEncoding(charset); 只對(duì)消息體中的數(shù)據(jù)起作用,對(duì)于URI字段中的參數(shù)不起作用,我們通常通過下面的代碼來完成編碼轉(zhuǎn)換:

           

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

           

          但是每次進(jìn)行這樣的轉(zhuǎn)換實(shí)在是很麻煩,有沒有統(tǒng)一的解決方案呢?

           

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

           

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

           

          這樣做的缺點(diǎn)是,同一個(gè)tomcat下的其他應(yīng)用也將受到影響。而其每次部署時(shí)都需要類修改配置也很麻煩。

           

          解決方案2:自定義請(qǐng)求包裝器包裝請(qǐng)求,將字符編碼轉(zhuǎn)換的工作添加到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.      * 獲得被裝飾對(duì)象的引用和采用的字符編碼 
          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.      * 實(shí)際上就是調(diào)用被包裝的請(qǐng)求對(duì)象的getParameter方法獲得參數(shù),然后再進(jìn)行編碼轉(zhuǎn)換 
          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("編碼轉(zhuǎn)換之前:" + 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.         //設(shè)置請(qǐng)求響應(yīng)字符編碼  
          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("----請(qǐng)求被"+config.getFilterName()+"過濾");  
          15.         //傳遞給目標(biāo)servlet或jsp的實(shí)際上時(shí)包裝器對(duì)象的引用,而不是原始的HttpServletRequest對(duì)象  
          16.         chain.doFilter(req, response);  
          17.           
          18.         System.out.println("----響應(yīng)被"+config.getFilterName()+"過濾");  
          19.   
          20.     }  

           

          這樣一來,在servlet中調(diào)用包裝器的getParameters方法來獲取參數(shù),就已經(jīng)完成了字符編碼的轉(zhuǎn)換過程,我們就不需要在每次獲取參數(shù)時(shí)來進(jìn)行字符編碼轉(zhuǎn)換了。


          其實(shí)用動(dòng)態(tài)代理來實(shí)現(xiàn)可能更好,這里只是我講課時(shí)的一個(gè)例子,用來介紹HttpServletRequestWrapper,不對(duì)之處,敬請(qǐng)指教,以免誤人子弟啊。


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


          學(xué)軟件開發(fā),到蜂鳥科技!
          超強(qiáng)的師資力量 、完善的課程體系 、超低的培訓(xùn)價(jià)格 、真實(shí)的企業(yè)項(xiàng)目。

          網(wǎng)址:www.ntcsoft.com 
          電話:0371-63839606 
          鄭州軟件開發(fā)興趣小組群:38236716

           

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

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          留言簿(2)

          我參與的團(tuán)隊(duì)

          文章檔案(22)

          搜索

          •  

          最新評(píng)論

          主站蜘蛛池模板: 甘洛县| 双鸭山市| 黄浦区| 新丰县| 鹰潭市| 海城市| 洛阳市| 曲水县| 微博| 齐齐哈尔市| 福安市| 札达县| 托克逊县| 梅河口市| 光山县| 定陶县| 延津县| 新密市| 仙桃市| 建湖县| 海安县| 新民市| 尼勒克县| 武定县| 上栗县| 永年县| 临高县| 鸡东县| 丁青县| 章丘市| 寻甸| 象州县| 中阳县| 平远县| 叶城县| 东丰县| 长丰县| 夏津县| 彩票| 灯塔市| 湖州市|