Servlet处理get请求时的中文乱码问题

来源:http://mycloudream.github.io

我们都知道,使用Servlet处理get请求时,如果get请求的参数中有中文,直接接收会是乱码,这个时候我们使用类似下面的语句来处理乱码:

1 String name = request.getParameter("name");
2 System.out.prinlnt(name); // 乱码
3 // 处理乱码
4 name = new String(name.getBytes("ISO8859-1"),"UTF-8");
5 System.out.println(name);// 乱码问题解决

这时候每次中文都要处理,比较麻烦,我们可能会使用过滤器,使用类型下面的代码处理乱码问题:

 1 public String getParameter(String name) {
 2     String value = super.getParameter(name);
 3     if (value == null)
 4         return null;
 5     String method = request.getMethod();
 6     if ("get".equalsIgnoreCase(method)) {
 7         try {
 8             value = new String(value.getBytes("ISO8859-1"),"UTF-8");
 9         } catch (UnsupportedEncodingException e) {
10             e.printStackTrace();
11         }
12     }
13     return value;
14 }

但是,这是为什么呢?为什么我们需要将ISO8859-1转为UTF-8?为什么我们接收到的参数是ISO8859-1这种编码方式的?

其实很简单,只是个配置问题:

在tomcat安装目录下的conf/server.xml中,有如下的配置:

1 <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

我们可能改动过这里的port为9999,8888等自己喜欢的端口号,这里呢,也可以设置另外一个跟上述编码问题有关的参数信息:URIEncoding,该配置决定了使用get请求通过浏览器地址栏访问tomcat时的编码方式,默认的编码方式使ISO8859-1,这一点我们可以从官网文档(https://tomcat.apache.org/tomcat-7.0-doc/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.

知道了这点,接下来就简单了,我们可以这样配置,则上述代码中,就不需要再从ISO8859-1转为UTF-8了:

1 URIEncoding="UTF-8"

这显然比上述两种方式简单多了。

值得注意的是,从tomcat8.0开始,URIEncoding默认值不再是ISO8859-1,而变成了UTF-8 

官方文档 (https://tomcat.apache.org/tomcat-8.0-doc/config/http.html) 中是这么说的:

URIEncoding:This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, UTF-8 will be used unless the org.apache.catalina.STRICT_SERVLET_COMPLIANCE system property is set to true in which case ISO-8859-1 will be used.

那么也就意味着,从tomcat8.0开始,get请求中的中文参数,不需要特殊处理了。而如果是tomcat8之前的项目要迁移到tomcat8上面来,则也需要特殊注意这个问题,可能要删减代码中响应乱码的处理模块了。

 

Servlet中统一处理各版本tomcat的get和post请求的乱码问题

 

Filter是这样一种Java类:

在request到达servlet的服务方法之前拦截HttpServletRequest对象

在服务方法转移控制后又能拦截HttpServletResponse对象,处理这些响应

它功能非常强大,一般Servlet中的乱码问题也使用它来解决。

 1 package cn.ucai.superwechat.filter;
 2 import java.io.IOException;
 3 import java.io.UnsupportedEncodingException;
 4 import javax.servlet.Filter;
 5 import javax.servlet.FilterChain;
 6 import javax.servlet.FilterConfig;
 7 import javax.servlet.ServletContext;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.annotation.WebFilter;
12 import javax.servlet.http.HttpServletRequest;
13 import javax.servlet.http.HttpServletRequestWrapper;
14 import javax.servlet.http.HttpServletResponse;
15 @WebFilter(filterName = "characterEncodingFilter", urlPatterns = "/*")
16 public class CharacterEncodingFilter implements Filter {
17     private String encode = "UTF-8";// 默认UTF-8编码
18     public void init(FilterConfig filterConfig) throws ServletException {
19         String encoding = filterConfig.getInitParameter("encode");
20         if (encoding != null) {
21             encode = encoding;
22         }
23     }
24     public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
25             throws IOException, ServletException {
26         HttpServletRequest request = (HttpServletRequest) req;
27         HttpServletResponse response = (HttpServletResponse) resp;
28         // 设置request编码
29         request.setCharacterEncoding(encode);
30         int serverVision = getServerVision(request);
31         // 设置相应信息
32         response.setContentType("text/html;charset=" + encode);
33         response.setCharacterEncoding(encode);
34         if (serverVision <= 7) {
35             chain.doFilter(new CharacterEncodingRequest(request), response);
36         } else {
37             chain.doFilter(request, response);
38         }
39     }
40     /**
41      * 得到当前运行tomcat的版本信息
42      * 
43      * @param request
44      * @return
45      */
46     private int getServerVision(HttpServletRequest request) {
47         ServletContext context = request.getServletContext();
48         String serverInfo = context.getServerInfo();// 得到服务器信息,例如:Apache
49                                                     // Tomcat/7.0.39
50         int serverVision = Integer.parseInt(serverInfo.substring(serverInfo.indexOf("/") + 1, serverInfo.indexOf(".")));
51         return serverVision;
52     }
53     public void destroy() {
54         System.out.println("destroy");
55     }
56 }
57 /**
58  * 对Get方式传递的请求参数进行编码
59  */
60 class CharacterEncodingRequest extends HttpServletRequestWrapper {
61     private HttpServletRequest request = null;
62     public CharacterEncodingRequest(HttpServletRequest request) {
63         super(request);
64         this.request = request;
65     }
66     /**
67      * 对参数重新编码
68      */
69     @Override
70     public String getParameter(String name) {
71         String value = super.getParameter(name);
72         if (value == null)
73             return null;
74         String method = request.getMethod();
75         if ("get".equalsIgnoreCase(method)) {
76             try {
77                 value = new String(value.getBytes("ISO8859-1"), request.getCharacterEncoding());
78             } catch (UnsupportedEncodingException e) {
79                 e.printStackTrace();
80             }
81         }
82         return value;
83     }
84 }
posted @ 2017-02-24 00:22  g29tony  阅读(306)  评论(0)    收藏  举报