星期一, 二月 20, 2006
再谈tomcat 5.x环境下的字符编码问题
@see "Tomcat环境下,字符编码的filter"
确实比较晕,tomcat server让多字节编码的国家吃尽苦头
原先以为,加这么个filter就一了百了了,实际上要复杂的多
原因是,这个filter的方法对tomcat 4.x版本是起作用的,但是在tomcat 5以后,就不完全适合了
为什么呢?
因为在http method是GET的时候,tomcat server 5.x会根据server.xml配置中<Connector>元素的URIEncoding属性设置,自己处理字符编码(此处讨论,不考虑主要是为了和tomcat 4兼容的useBodyEncodingForURI属性)
这也就意味着,如果你使用tomcat 5.x,你必须在doFilter的时候,区分http请求的方法是GET还是POST,如果是POST,调用request.setCharacterEncoding(encoding)来处理字符编码;如果是GET,则应当将这转换编码的工作交给tomcat server。为了让tomcat能正常处理你的字符编码,必须注意要设置正确的URIEncoding属性。譬如,网页编码是GBK的,则应当设置URIEncoding="GBK",特别的,如果需要生成URL的,则URL中的中文字符必须转码成符合GBK编码的%xx的格式。
对于使用GBK编码,使用tomcat 5.x server的网站,如下的配置和设计是正确的:
1)<Connector ... URIEncoding="GBK" ... />
2)使用filter,encoding=GBK
3)filter中区分http请求,代码如下:
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
// Conditionally select and set the character encoding to be used
if (ignore || (request.getCharacterEncoding() == null)) {
String encoding = selectEncoding(request);
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (encoding != null && httpServletRequest.getMethod().equalsIgnoreCase("POST"))
request.setCharacterEncoding(encoding);
}
// Pass control on to the next filter
chain.doFilter(request, response);
}
4)直接使用URL的,如果URL中的参数值包含中文,则必须根据GBK的编码方式将每个中文字符转成%xx%xx的格式,如:<A href="/search.shtml?action=search&key=%CC%AB%D1%F4%C4%DC">太阳能</A>