项目场景:
今天测试程序时,新增数据后,回显数据全部为乱码。
问题描述:
新增数据后,回显数据全部为乱码,数据库中的测试数据,保存的也均为乱码,直接调用接口Get方式不为乱码。
原因分析:
首先,通过在浏览器的F12中查看前端传递的参数是否为乱码,发现不是乱码。然后,在Action中打印接收的参数,发现参数在Action接收之前就变成乱码了,由此确定是前端和后端传输数据之间出现了问题。然后想通过在第一个过滤器中打印一下参数,看看是否为乱码,直接打印之前在过滤器写中的request.getParameter方法获取参数。发现打印结果仍为乱码,查看修改编码为UTF-8的过滤器,发现这个过滤器在测试过滤器的后面执行,尝试调换两者位置,发现乱码解决。但是两者程序未调换之前,程序一直未发现异常,所以从最近对过滤器的修改入手,查找问题,最终发现问题出在过滤器的request.getParameter()方法中。
源码分析:
通过查看request.getParameter()的源码,可以见到,request.getParameter()的时候会先判断是否曾经解析过编码,如果编过码,会直接返回,否则会进行一次默认编码,故此如果直接使用getParameter()会将编码格式默认为ISO-8859-1
public String getCharacterEncoding() {
if (charEncoding != null)
return charEncoding;charEncoding = ContentType.getCharsetFromContentType(getContentType());
return charEncoding;}
而在encodingFilter过滤器中,如果request.getCharacterEncoding() == null的情况下 ,才会重新编码,故此造成乱码,所以要将编码的过滤器提到最前面运行。
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
request.setCharacterEncoding(this.encoding);
if (this.forceEncoding) {
response.setCharacterEncoding(this.encoding);
}
}
filterChain.doFilter(request, response);
}