来自:http://www.javaeye.com/topic/483158java
应用一:解决tomcat下中文乱码问题(先来个简单的) web
在tomcat下,咱们一般这样来解决中文乱码问题:tomcat
过滤器代码:app
package filter; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import wrapper.GetHttpServletRequestWrapper; public class ContentTypeFilter implements Filter { private String charset = "UTF-8"; private FilterConfig config; public void destroy() { System.out.println(config.getFilterName()+"被销毁"); charset = null; config = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //设置请求响应字符编码 request.setCharacterEncoding(charset); response.setCharacterEncoding(charset); HttpServletRequest req = (HttpServletRequest)request; System.out.println("----请求被"+config.getFilterName()+"过滤"); //执行下一个过滤器(若是有的话,不然执行目标servlet) chain.doFilter(req, response); System.out.println("----响应被"+config.getFilterName()+"过滤"); } public void init(FilterConfig config) throws ServletException { this.config = config; String charset = config.getServletContext().getInitParameter("charset"); if( charset != null && charset.trim().length() != 0) { this.charset = charset; } } }
web.xml中过滤器配置:jsp
<context-param> <param-name>charset</param-name> <param-value>UTF-8</param-value> </context-param> <filter> <filter-name>ContentTypeFilter</filter-name> <filter-class>filter.ContentTypeFilter</filter-class> </filter> <filter-mapping> <filter-name>ContentTypeFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
request.setCharacterEncoding(charset); 必须写在第一次使用request.getParameter()以前,这样才能保证参数是按照已经设置的字符编码来获取。
response.setCharacterEncoding(charset);必须写在PrintWriter out = request.getWriter()以前,这样才能保证out按照已经设置的字符编码来进行字符输出。post
经过过滤器,咱们能够保证在Servlet或JSP执行以前就设置好了请求和响应的字符编码。this
可是这样并不能彻底解决中文乱码问题:编码
对于post请求,不管是“获取参数环节”仍是“输出环节"都是没问题的;url
对于get请求,"输出环节"没有问题,可是"获取参数环节"依然出现中文乱码,因此在输出时直接将乱码输出了。spa
缘由是post请求和get请求存放参数位置是不一样的:
post方式参数存放在请求数据包的消息体中。get方式参数存放在请求数据包的请求行的URI字段中,以?开始以param=value¶me2=value2的形式附加在URI字段以后。而request.setCharacterEncoding(charset); 只对消息体中的数据起做用,对于URI字段中的参数不起做用,咱们一般经过下面的代码来完成编码转换:
可是每次进行这样的转换实在是很麻烦,有没有统一的解决方案呢?
解决方案1: 在tomcat_home\conf\server.xml 中的Connector元素中设置URIEncoding属性为合适的字符编码
这样作的缺点是,同一个tomcat下的其余应用也将受到影响。而其每次部署时都须要类修改配置也很麻烦。
解决方案2:自定义请求包装器包装请求,将字符编码转换的工做添加到getParameter()方法中
package wrapper; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class GetHttpServletRequestWrapper extends HttpServletRequestWrapper { private String charset = "UTF-8"; public GetHttpServletRequestWrapper(HttpServletRequest request) { super(request); } /** * 得到被装饰对象的引用和采用的字符编码 * @param request * @param charset */ public GetHttpServletRequestWrapper(HttpServletRequest request, String charset) { super(request); this.charset = charset; } /** * 实际上就是调用被包装的请求对象的getParameter方法得到参数,而后再进行编码转换 */ public String getParameter(String name) { String value = super.getParameter(name); value = value == null ? null : convert(value); return value; } public String convert(String target) { System.out.println("编码转换以前:" + target); try { return new String(target.trim().getBytes("ISO-8859-1"), charset); } catch (UnsupportedEncodingException e) { return target; } } } 修改过滤器的doFilter方法 代码如
下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //设置请求响应字符编码 request.setCharacterEncoding(charset); response.setCharacterEncoding(charset); //新增长的代码 HttpServletRequest req = (HttpServletRequest)request; if(req.getMethod().equalsIgnoreCase("get")) { req = new GetHttpServletRequestWrapper(req,charset); } System.out.println("----请求被"+config.getFilterName()+"过滤"); //传递给目标servlet或jsp的实际上时包装器对象的引用,而不是原始的HttpServletRequest对象 chain.doFilter(req, response); System.out.println("----响应被"+config.getFilterName()+"过滤"); }
这样一来,在servlet中调用包装器的getParameters方法来获取参数,就已经完成了字符编码的转换过程,咱们就不须要在每次获取参数时来进行字符编码转换了。