解决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 }
|