A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

解决GETPOST请求中文乱码问题

对于做Java WEB项目同学来说,中文乱码问题是一个经常遇到而又非常头痛的问题,而最容易出现乱码的环节就是在浏览器向服务器发送请求的过程本文将介绍乱码产生的原因以及如何有效解决web请求中的乱码问题,其实解决方法有很多种,不同的请求类型解决方法也不相同。
一、乱码产生的原因
客户端(即浏览器)把URL经过编码后发送给服务器,但是由于客户端本身并没有遵循URI编码的规范(http://www.w3.org/International/O-URL-code.html),为了支持中文解析使用的是UTF-8的编码格式进行编写。但是由于服务器一般使用ISO-8859-1的编码格式,对传输过来的URL进行解码。由于编码和解码不一致,所以后台接受中文数据的时候,会出现乱码的问题。如图1所示。
图一:乱码产生原因
二、Get请求解决中文乱码
首先提供页面
1 <h1>GET方式</h1>
2 <form method="get" action="getRequest">
3         用户名<input type="text" name="username"/><br/>
4         <input type="submit" value="提交"/>
5 </form>
注解:
这里提供的是html页面,提交方式是get请求,提交路径是getRequest。
GET方式的第一种方案
修改服务器默认的编码方式(不推荐)(本案例以tomcat服务器为例)。默认情况下,tomcat使用的编码方式:iso-8859-1。修改tomcat下的conf/server.xml文件,找到如下代码:   

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

        这段代码规定了Tomcat监听HTTP请求的端口号等信息。可以在这里添加一个属性:URIEncoding,将该属性值设置为UTF-8,即可让Tomcat(默认ISO-8859-1编码)以UTF-8的编码处理get请求。
修改完成后:
<Connector port="8080"  protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
备注:
此方法不是很常用,如果两个项目:一个是UTF-8,另一个是GBK,修改tomcat的servlet.xml会很死板。
GET方式的第二种方案:先编码再解码
如图1所示,产生乱码的原因是由于浏览器用UTF-8进行编码,服务器用ISO-8859-1进行解码,编解码不一致。如果在后台程序中,对传输过来的数据先用ISO-8859-1进行编码,再用UTF-8进行解码,这样前后端编解码保持一直,也能解决乱码问题。如图2所示。
2:先编码再解码的解决乱码示意图
提供代码展示一:
1 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2                 //获取页面传输过来的数据
3                 String username = request.getParameter("username");
4                 //先对数据使用ISO-8859-1进行编码
5                 username =URLEncoder.encode(username, "iso_8859-1");
6                 //再对数据使用UTF-8进行解码
7                 username=URLDecoder.decode(username, "UTF-8");
8                 //进行打印
9                 System.out.println(username);
10         }
提供代码方式二:
1 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2                 //获取页面传输过来的数据
3                 String username = request.getParameter("username");
4                 //先对数据使用ISO-8859-1进行编码,得到字节数组
5                 byte[] bytes = username.getBytes("ISO-8859-1");
6                 //再对字节数组用UTF-8解码的方式转化成字符串
7                 username = new String(bytes,"UTF-8");
8                 //进行打印
9                 System.out.println(username);
10         }
三、POST请求解决中文乱码
首先提供页面:
1 <h1>POST方式</h1>
2 <form method="post" action="postRequest">
3         用户名:<input type="text" name="username"/><br/>
4         <input type="submit" value="提交"/>
5 </form>
注解:
这里提供的是html页面,提交方式是post请求,提交路径是postRequest。
POST方式的第一种方案
此方法与GET请求方式相同,先用ISO-8859-1进行编码,再用UTF-8进行解码。
代码展示:
1 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2                 //获取页面传输过来的数据
3                 String username = request.getParameter("username");
4                 //先用ISO-8859-1进行编码,再用UTF-8进行解码,与get请求解决方式相同
5                        username = new String(username.getBytes("ISO-8859-1"),"UTF-8");
6                 //进行打印
7                   System.out.println(username);     
8         }
POST方式的第二种解决方案:设置请求编码
设置请求编码集,这种方式只对请求体有效,post有请求体,故可行。这种方式算是post的偷懒方式,开发时最常用。
提供代码展示:
1 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2                 //设置请求编码集
3                 request.setCharacterEncoding("UTF-8");
4                 //获取页面传输过来的数据
5                 String username = request.getParameter("username");
6                 //进行打印
7                   System.out.println(username);     
8         }
备注:
此方法设置请求编码集的代码需要放在获取数据代码之前才能生效。
四、配置全站乱码过滤器    
可以使用编码过滤器来解决,要注意的是它的位置一定要是第一个执行的过滤器。
web.xml中配置过滤器:
1  <filter>
2     <filter-name>GenericEncodingFilter</filter-name>
3     <filter-class>cn.demo.filter.GenericEncodingFilter</filter-class>
4   </filter>
5   <filter-mapping>
6     <filter-name>GenericEncodingFilter</filter-name>
7     <url-pattern>/*</url-pattern>
8   </filter-mapping>
过滤器提供代码展示:GenericEncodingFilter.java
1 package cn.demo.filter;
2 import java.io.IOException;
3 import java.io.UnsupportedEncodingException;
4 import java.util.Map;
5 import javax.servlet.Filter;
6 import javax.servlet.FilterChain;
7 import javax.servlet.FilterConfig;
8 import javax.servlet.ServletException;
9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletRequestWrapper;
13 import javax.servlet.http.HttpServletResponse;
14
15 /**
16  * 解决getpost请求 全部乱码
17  */
18 public class GenericEncodingFilter implements Filter {
19         @Override
20         public void destroy() {
21         }
22         @Override
23         public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
24                 // 转型为与协议相关对象
25                 HttpServletRequest httpServletRequest = (HttpServletRequest) request;
26                 HttpServletResponse httpServletResponse = (HttpServletResponse) response;
27                 httpServletResponse.setContentType("text/html;charset=utf-8");
28                 // request包装增强               
29                 HttpServletRequest myrequest = new MyRequest(httpServletRequest);
30                 chain.doFilter(myrequest, httpServletResponse);
31         }
32         @Override
33         public void init(FilterConfig filterConfig) throws ServletException {
34         }
35 }
36 // 自定义request对象
37 class MyRequest extends HttpServletRequestWrapper {
38         private HttpServletRequest request;
39         private boolean hasEncode;
40         public MyRequest(HttpServletRequest request) {
41                 super(request);// super必须写
42                 this.request = request;
43         }
44         // 对需要增强方法 进行覆盖
45         public Map getParameterMap() {
46                 // 先获得请求方式
47                 String method = request.getMethod();
48                 if (method.equalsIgnoreCase("post")) {
49                         // post请求
50                         try {
51                                 // 处理post乱码
52                                 request.setCharacterEncoding("utf-8");
53                                 return request.getParameterMap();
54                         } catch (UnsupportedEncodingException e) {
55                                 e.printStackTrace();
56                         }
57                 } else if (method.equalsIgnoreCase("get")) {
58                         // get请求
59                         Map<String, String[]> parameterMap = request.getParameterMap();
60                         if (!hasEncode) { // 确保get手动编码逻辑只运行一次
61                                 for (String parameterName : parameterMap.keySet()) {
62                                         String[] values = parameterMap.get(parameterName);
63                                         if (values != null) {
64                                                 for (int i = 0; i < values.length; i++) {
65                                                         try {
66                                                                 // 处理get乱码
67                                                                 values = new String(values.getBytes("ISO-8859-1"), "utf-8");
68                                                         } catch (UnsupportedEncodingException e) {
69                                                                 e.printStackTrace();
70                                                         }
71                                                 }
72                                         }
73                                 }
74                                 hasEncode = true;
75                         }
76                         return parameterMap;
77                 }
78                 return super.getParameterMap();
79         }
80         @Override
81         public String getParameter(String name) {
82                 Map<String, String[]> parameterMap = getParameterMap();
83                 String[] values = parameterMap.get(name);
84                 if (values == null) {
85                         return null;
86                 }
87                 return values[0]; // 取回参数的第一个值
88         }
89         @Override
90         public String[] getParameterValues(String name) {
91                 Map<String, String[]> parameterMap = getParameterMap();
92                 String[] values = parameterMap.get(name);
93                 return values;
94         }
95 }

4 个回复

倒序浏览
回复 使用道具 举报
奈斯,很赞
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马