黑马程序员技术交流社区
标题: 【上海校区】解决GET和POST请求中文乱码问题 [打印本页]
作者: yuchengmin 时间: 2018-7-25 23:16
标题: 【上海校区】解决GET和POST请求中文乱码问题
解决GET和POST请求中文乱码问题
对于做Java WEB项目同学来说,中文乱码问题是一个经常遇到而又非常头痛的问题,而最容易出现乱码的环节就是在浏览器向服务器发送请求的过程。本文将介绍乱码产生的原因以及如何有效解决web请求中的乱码问题,其实解决方法有很多种,不同的请求类型解决方法也不相同。
一、乱码产生的原因图一:乱码产生原因
二、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 * 解决get和post请求 全部乱码
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 }
作者: 摩西摩西OvO 时间: 2018-7-26 09:10

作者: 不二晨 时间: 2018-7-26 11:30
奈斯,很赞
作者: 吴琼老师 时间: 2018-7-26 15:26
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |