Spring的filter與Tomcat的get和post

使用Tomcat 5.0.20,我們使用Form submit 的數據將會以ISO8859-1處理,我們必須自己將字符串轉換爲GB2312/GBK(簡體中文),在web程序中,對所有的 request.getParameter("xx"); 作了 toGBKString() 的處理,發現還是出現了中文問題,中文還是可能變成亂碼!

       經過分析,發現問題出在 QueryString的處理上,在使用 Tomcat 4.x時,對於 SUBMIT 時無論採用 GET or POST,Tomcat server 對 parameters 的處理都採用ISO8859-1處理,但在 Tomcat 5.x 版,將get請求獨立出來,如果Form 的 Method 採用 GET 及或者在 URL 上的寫中文,上傳到 Tomcat時,無論如何轉碼,都是亂碼,即使使用 URLEncode結果也一樣。

       通過研究tomcat的文檔可以找到解決辦法,在$TOMCAT_HOME/webapps/tomcat-docs/config/http.html 中寫道

CODE:

URIEncoding:
       This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.
       useBodyEncodingForURI:
       This specifies if the encoding specified in contentType should be used for URI query parameters, instead of using the URIEncoding. This setting is present for compatibility with Tomcat 4.1.x, where the encoding specified in the contentType, or explicitely set using Request.setCharacterEncoding method was also used for the parameters from the URL. The default value is false
以上 Tomcat 參數,是設定在 server.xml 中的 http <Connector />中,必須設定這兩個參數其中之一。
       URIEncoding 設定爲 URIEncoding="ISO-8859-1" 指定爲 "ISO-8859-1" 編碼,讓 QueryString 的編碼與 post body 相同。
       useBodyEncodingForURI 用來兼容 Tomcat 4.x 版的,值是 "true" or "false",指 "要不要讓 QueryString 與 POST BODY 採用相同的編碼 ",設成 true,就可以做到 "ISO-8859-1" 編碼。

       建議採用 URIEncoding 的設定,因爲 useBodyEncodingForURI是爲了兼容 Tomcat 4.X。不過按照原文的說明,這兩個參數都不設,Tomcat 也應該採用 "ISO-8859-1" 的編碼,爲什麼還是有問題呢?只好看 Tomcat Source Code了,在org.apache.tomcat.util.http.Parameters類,Tomcat用來處理QueryString:

CODE:

private String urlDecode(ByteChunk bc, String enc)
        throws IOException {
        if( urlDec==null ) {
            urlDec=new UDecoder();   
        }
        urlDec.convert(bc);
        String result = null;
        if (enc != null) {
            bc.setEncoding(enc);
            result = bc.toString();
        } else {
            CharChunk cc = tmpNameC;
            cc.allocate(bc.getLength(), -1);
            // Default encoding: fast conversion
            byte[] bbuf = bc.getBuffer();
            char[] cbuf = cc.getBuffer();
            int start = bc.getStart();
            for (int i = 0; i < bc.getLength(); i++) {
                cbuf[i] = (char) (bbuf[i + start] & 0xff);
            }
            cc.setChars(cbuf, 0, bc.getLength());
            result = cc.toString();
            cc.recycle();
        }
        return result;
    }
tomcat 處理 QueryString時,如果沒有設定 encode,並沒有採用 ISO-8859-1 的編碼,而是用 fast conversion 來處理,纔會造成中文問題,所以必須在 Server.xml 中加上 URLEncoding 的參數才行.
     
      Connector 的設定
     <Connector acceptCount="100"cdisableUploadTimeout="true"port="80"redirectPort="8443"enableLookups="false"minSpareThreads="25"maxSpareThreads="75"maxThreads="150"maxPostSize="0"URIEncoding="ISO-8859-1"></Connector>

      所以在使用 Tomcat 4 通過 GET or POST 的方式傳參數時,通常都是使用 Filter 的方式解決中文傳參數的問題。但是到了 Tomcat 5.0.20 之後,解決中文傳參數的問題,就必須考慮是使用 GET or POST,兩種的方式不同。

      使用 GET 的方式

CODE:

String name = new String((request.getParameter("name")).getBytes("ISO-8859-1"),"GBK");使用 POST 的方式

CODE:

request.setCharacterEncoding("GBK");如果設定URIEncoding="UTF-8"和使用 IE, 設定總是以 UTF8發送URL,你還可以用<img src="我的圖片.jpg" />

      使用Filter的處理 :先判斷是使用那種方式( GET or POST),假若是用 GET 的方式就採用第一個;若使用POST 方式,就採用第二個

CODE:

HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (httpServletRequest.getMethod().equals("POST"))
{        request.setCharacterEncoding("UTF-8");}
else if (httpServletRequest.getMethod().equals("GET"))
{
         //進行處理
}
注意Spring的filter沒有解決這個問題,以下是它的代碼

CODE:

protected void doFilterInternal(
   HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
   throws ServletException, IOException {
  
  if (this.forceEncoding || request.getCharacterEncoding() == null) {
   request.setCharacterEncoding(this.encoding);
  }
  filterChain.doFilter(request, response);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章