转自: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
- <!--将采用的字符编码配置成应用初始化参数而不是过滤器私有的初始化参数是由于在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字段中的参数不起做用,咱们一般经过下面的代码来完成编码转换:
- String paramValue = request.getParameter("paramName");
- paramValue = new String(paramValue.trim().getBytes("ISO-8859-1"), charset);
可是每次进行这样的转换实在是很麻烦,有没有统一的解决方案呢?
解决方案1: 在tomcat_home\conf\server.xml 中的Connector元素中设置URIEncoding属性为合适的字符编码
- <Connector port="8080" protocol="HTTP/1.1"
- connectionTimeout="20000"
- redirectPort="8443"
- URIEncoding="UTF-8"
- />
这样作的缺点是,同一个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方法来获取参数,就已经完成了字符编码的转换过程,咱们就不须要在每次获取参数时来进行字符编码转换了。