为应用添加一个 CharsetFilter 是极其普通的事情,做的事情无非是 request.setCharseterEncoding(xxx),如果需要,response可能也会动动。
如此简单,依然出了乱码问题。看代码:
1
public
void
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws
IOException, ServletException {
2 log.info( " response.isCommitted() => " + response.isCommitted());
3 if (response.isCommitted()) {
4 HttpServletRequest req = (HttpServletRequest) request;
5 HttpServletResponse resp = (HttpServletResponse) response;
6 Cookie[] cks = req.getCookies();
7 for ( int i = 0 ; cks != null && i < cks.length; i ++ ) {
8 log.info( " cookie:/t " + cks[i].getName() + " => " + cks[i].getValue());
9 }
10 java.util.Enumeration < String > enu = req.getHeaderNames();
11 while (enu.hasMoreElements()) {
12 String s = enu.nextElement();
13 log.info( " header:/t " + s + " => " + req.getHeader(s));
14 }
15 log.info( " response.getCharacterEncoding() => " + response.getCharacterEncoding());
16 log.info( " response.getLocale().getLanguage() => " + response.getLocale().getLanguage());
17 log.info( " response.getContentType() => " + response.getContentType());
18 log.info( " request.getRequestURI() => " + req.getRequestURI());
19 throw ( new IOException( " ----xxx--->>> response is committed. " ));
20 }
21
22 response.setCharacterEncoding(encoding);
23 response.setContentType( " text/html; charset=utf-8 " );
24 chain.doFilter(request, response);
25 response.setCharacterEncoding(encoding);
26 response.setContentType( " text/html; charset=utf-8 " );
27 }
28
2 log.info( " response.isCommitted() => " + response.isCommitted());
3 if (response.isCommitted()) {
4 HttpServletRequest req = (HttpServletRequest) request;
5 HttpServletResponse resp = (HttpServletResponse) response;
6 Cookie[] cks = req.getCookies();
7 for ( int i = 0 ; cks != null && i < cks.length; i ++ ) {
8 log.info( " cookie:/t " + cks[i].getName() + " => " + cks[i].getValue());
9 }
10 java.util.Enumeration < String > enu = req.getHeaderNames();
11 while (enu.hasMoreElements()) {
12 String s = enu.nextElement();
13 log.info( " header:/t " + s + " => " + req.getHeader(s));
14 }
15 log.info( " response.getCharacterEncoding() => " + response.getCharacterEncoding());
16 log.info( " response.getLocale().getLanguage() => " + response.getLocale().getLanguage());
17 log.info( " response.getContentType() => " + response.getContentType());
18 log.info( " request.getRequestURI() => " + req.getRequestURI());
19 throw ( new IOException( " ----xxx--->>> response is committed. " ));
20 }
21
22 response.setCharacterEncoding(encoding);
23 response.setContentType( " text/html; charset=utf-8 " );
24 chain.doFilter(request, response);
25 response.setCharacterEncoding(encoding);
26 response.setContentType( " text/html; charset=utf-8 " );
27 }
28
这个 Filter 在 web.xml 中,定义在 Filter Chain 中的第一个。
而出错日志则是这样的:
03
Feb
2009
18
:
48
:
20
(CharsetFilter.java:
31
) INFO - response.isCommitted()
=
> true
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 37 ) INFO - cookie: JSESSIONID = > A6293E5AAC56D62B9A0AA63E6C4B4935
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 37 ) INFO - cookie: user_request_locale = > zh_CN
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: user-agent = > Mozilla/ 5.0 (Windows ; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.43 Safari/525.19
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: referer = > http:// 192.168.1.212 : 8180 /mw/customerHome.action
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: accept = > text/xml , application/xml , application/xhtml+xml , text/html ; q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: accept-encoding = > gzip , deflate , bzip2 , sdch
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: cookie = > JSESSIONID = A6293E5AAC56D62B9A0AA63E6C4B4935 ; user_request_locale=zh_CN
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: accept-language = > zh-CN , zh
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: accept-charset = > gb18030 , * , utf- 8
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: if-none-match = > W/ " 1296-1233658401000 "
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: if-modified-since = > Tue , 03 Feb 2009 10 : 53 : 21 GMT
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: host = > 192.168.1.212 : 8180
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: connection = > Keep-Alive
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 44 ) INFO - response.getCharacterEncoding() = > ISO- 8859 - 1
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 45 ) INFO - response.getLocale().getLanguage() = > en
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 46 ) INFO - response.getContentType() = > null
03 Feb 2009 18 : 48 : 20 (StandardWrapperValve.java: 225 ) WARN - Servlet.service() for servlet default threw exception
java.io.IOException:
at cn.vbl.mw.web.filter.CharsetFilter.doFilter(CharsetFilter.java: 47 )
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java: 202 )
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java: 173 )
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java: 213 )
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java: 178 )
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java: 126 )
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java: 105 )
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java: 107 )
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java: 148 )
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java: 869 )
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java: 664 )
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java: 527 )
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java: 80 )
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java: 684 )
at java.lang.Thread.run(Thread.java: 595 )
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 37 ) INFO - cookie: JSESSIONID = > A6293E5AAC56D62B9A0AA63E6C4B4935
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 37 ) INFO - cookie: user_request_locale = > zh_CN
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: user-agent = > Mozilla/ 5.0 (Windows ; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/1.0.154.43 Safari/525.19
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: referer = > http:// 192.168.1.212 : 8180 /mw/customerHome.action
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: accept = > text/xml , application/xml , application/xhtml+xml , text/html ; q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: accept-encoding = > gzip , deflate , bzip2 , sdch
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: cookie = > JSESSIONID = A6293E5AAC56D62B9A0AA63E6C4B4935 ; user_request_locale=zh_CN
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: accept-language = > zh-CN , zh
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: accept-charset = > gb18030 , * , utf- 8
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: if-none-match = > W/ " 1296-1233658401000 "
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: if-modified-since = > Tue , 03 Feb 2009 10 : 53 : 21 GMT
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: host = > 192.168.1.212 : 8180
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 42 ) INFO - header: connection = > Keep-Alive
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 44 ) INFO - response.getCharacterEncoding() = > ISO- 8859 - 1
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 45 ) INFO - response.getLocale().getLanguage() = > en
03 Feb 2009 18 : 48 : 20 (CharsetFilter.java: 46 ) INFO - response.getContentType() = > null
03 Feb 2009 18 : 48 : 20 (StandardWrapperValve.java: 225 ) WARN - Servlet.service() for servlet default threw exception
java.io.IOException:
at cn.vbl.mw.web.filter.CharsetFilter.doFilter(CharsetFilter.java: 47 )
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java: 202 )
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java: 173 )
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java: 213 )
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java: 178 )
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java: 126 )
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java: 105 )
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java: 107 )
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java: 148 )
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java: 869 )
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java: 664 )
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java: 527 )
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java: 80 )
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java: 684 )
at java.lang.Thread.run(Thread.java: 595 )
不得其解
后记:
1. 两个地址
Bug 28331 – Unpredictable switch from UTF-8 to other encoding in Response https://issues.apache.org/bugzilla/show_bug.cgi?id=28331
Bug 28347 – Response committed before invocation of service method https://issues.apache.org/bugzilla/show_bug.cgi?id=28347
28347内写明了原因。
2. 解决方法
把 tomcat 的 security 加上就OK了。