在WEB开发的过程中,中文乱码是最为常见的问题之一。之所以会出现中文乱码的情况,主要原因是:前端使用POST或者GET方法传递的参数一般使用浏览器预先设置的编码方式进行编码,中文浏览器一般是使用UTF8或者GBK,英文的一般是ISO编码;而浏览器编码完成后发送给服务器,服务器进行解码的解码方式默认是使用ISO8859-1。这就造成了编码和解码方式不统一的,进而出现了中文乱码的问题。
在下面,我将给出分别对POST、GET方法乱码的解决方案
POST方法和GET方法是前端将表单中的内容提交到服务器端的方法,二者有着很大的不同之处。 首先,GET方法是直接把表单中的内容直接放在了URL中进行传值,就像这种:
可以很明显的看到,使用这种方式进行传参是对用户可见的,这就有了一定的安全隐患,所以,一般这种方法都不会用在对安全性有要求的地方。 其次,POST方法就相对安很多了,POST方法会将参数放入HTTP请求报文的实体部分,对用户来讲是不可见的。 对于HTTP的介绍,我今后会写一篇详细的博客来为大家讲解,细数HTTP协议的相关内容,敬请期待。
对于POST方法,解决起来相对简单。只需要在读取参数之前设置一下解码的的格式就行了。代码示例如下:
public class LoginServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response){
//将解码格式设置成UTF8
request.setCharacterEncoding("utf8");
String username = request.getParameter("username");
}
}
而对于GET方法,就是比较麻烦的了。 第一种方案是,拿到所有的从前端传递过来的参数,进行统一编码,然后是用正则表达式,字符串的split函数split(“&”)进行切割,切割完成后,再分别取出参数值。
//取出所有的参数
String allParameters = request.getQueryString();
//对参数重新编码
String parameters = java.net.URLDecoder.decode(allParameters,"UTF-8");
//正则分割
String[] parameter = parameters.split("&");
第二种方案就更麻烦了。 首先要做的是获取到请求的参数值,然后对这个参数值使用ISO-8859-1的格式分解成字节数组,然后再重新生成为一个编码格式是UTF8的字符串。
//获取参数值
String name = request.getParameter("name");
//把参数值变成字节数组
byte[] nameBytes = name.getBytes("ISO-8859-1");
//生成新的编码为UTF8的字符串
String newName = new String(nameBytes,"UTF-8");
很明显,如果我的服务端有着大量的Servlet,这样的做法会造成大量的代码重复,显然是不满足代码复用的要求的,于是我们选择使用过滤器,对请求进行过滤。 下面的这个文件是对两种请求方式的编码与解码。 EncodingRequest.java
public class EncodingRequest extends HttpServletRequestWrapper {
private String charset;
public EncodingRequest(HttpServletRequest request, String charset) {
super(request);
this.charset = charset;
}
public String getParameter(String name) {
HttpServletRequest request = (HttpServletRequest) getRequest();
String method = request.getMethod();
if(method.equalsIgnoreCase("post")) {
try {
request.setCharacterEncoding(charset);
} catch (UnsupportedEncodingException e) {}
} else if(method.equalsIgnoreCase("get")) {
String value = request.getParameter(name);
try {
value = new String(name.getBytes("ISO-8859-1"), charset);
} catch (UnsupportedEncodingException e) {
}
return value;
}
return request.getParameter(name);
}
}
这个文件是过滤器,将所有请求都进行过滤。
public class EncodingFilter extends HttpFilter {
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
String charset = this.getInitParameter("charset");
if(charset == null || charset.isEmpty()) {
charset = "UTF-8";
}
response.setCharacterEncoding(charset);
response.setContentType("text/html;charset=" + charset);
EncodingRequest res = new EncodingRequest(request, charset);
chain.doFilter(res, response);
}
}
最后,为了让过滤器工作,配置一下web.xml文件
<filter>
<filter-name>EncodingFilter</filter-name>
<!--包名及文件名-->
<filter-class>cn.roobtyan.filter.EncodingFilter</filter-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
做完如上工作,乱码就解决了。
感谢您的阅读,欢迎指正博客中存在的问题,也可以跟我联系,一起进步,一起交流!
微信公众号:进击的程序狗 邮箱:roobtyan@outlook.com 个人博客:http://roobtyan.cn