-- 作者:mfc42d
-- 发布时间:11/23/2005 5:46:00 PM
-- spring的filter与tomcat的get和post(转自我的blog)
使用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 中写道 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, 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 的设定 <Connectordebug="0"acceptCount="100"connectionTimeout="20000"disableUploadTimeout="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 的方式 String name = new String((request.getParameter("name")).getBytes("ISO-8859-1"),"GBK"); 使用 POST 的方式 request.setCharacterEncoding("GBK"); 如果设定URIEncoding="UTF-8"和使用 IE, 设定总是以 UTF8发送URL,你还可以用<img src="我的图片.jpg" /> 使用Filter的处理 :先判断是使用那种方式( GET or POST),假若是用 GET 的方式就采用第一个;若使用POST 方式,就采用第二个 HttpServletRequest httpServletRequest = (HttpServletRequest) request; if (httpServletRequest.getMethod().equals("POST")) { request.setCharacterEncoding("UTF-8");} else if (httpServletRequest.getMethod().equals("GET")) { //进行处理 } 注意spring的filter病没有解决这个问题,以下是他的代码 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); }
|