提出问题
当访问 .html 文件时,经过下面字符过滤器,会出现乱码
@WebFilter(urlPatterns = {"/*"})
public class CharacterFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
request.setCharacterEncoding("UTF-8");
// 访问html时,也经过此过滤器,由于先执行 resp.setContentType 设置编码,后执行 chain.doFilter(),导致 html 页面乱码
resp.setContentType("text/html; charset=UTF-8");
chain.doFilter(req, resp);
}
}
分析
访问html时,也经过此过滤器,由于先执行下面代码:
resp.setContentType("text/html; charset=UTF-8");
或者
resp.setCharacterEncoding(charset);
然后执行下面代码:
chain.doFilter(req, resp);
所以,将 html 页面返回给浏览器时,会携带下面请求头:
Content-Type: text/html; charset=UTF-8
由于有 charset=UTF-8 ,所以导致 html 乱码
不会乱码的请求头: Content-Type: text/html
解决(有bug)
@WebFilter(urlPatterns = {"/*"})
public class CharacterFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletResponse response = (HttpServletResponse) resp;
HttpServletRequest request = (HttpServletRequest) req;
request.setCharacterEncoding("UTF-8");
chain.doFilter(req, resp);
/* 移到 chain.doFilter() 下面,html可以正常显示
*
*/
resp.setContentType("text/html; charset=UTF-8");
}
}
缺点: 由于先执行 chain.doFilter(),也就是说,当访问 Servlet 时,也就先执行 serlvet ,后执行 resp.setContentType 设置编码,导致输出 json 乱码
完美解决
在过滤器中,判断访问 .html 文件,就不经过此过滤器,参看 javaweb Filter过滤器-设置字符集(可指定不过滤路径、文件)