乱码的问题是绕不开的一个问题,只要是web就绕不开;导致乱码的问题也是非常多的,不仅可能是服务器端的原因,也有可能是客户端设置了一个与服务器端不同的编码集…大致分为几类原因导致的乱码:
页面编码集与服务器端编码集不匹配导致
接受解析的时候乱码
响应页面的时候乱码
众所周知jsp页面最后是会被转化为一个servlet类的,这时候就需要注意页面设置的编码集与class文件的编码一致。
设置pageEncoding是编译解释时的编码,可以在每个jsp页面头部加上。而charset编码是只响应页面给用户时的编码。最好将pageEncoding与charset的编码集设置为同一个!
注意:指定charset时pageEncoding会使用相同的编码,因此pageEncoding是可以不设置的!
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%>
SpringMVC在解析参数时因为已经接受流并且已经编码了,这时候就有可能乱码。这种情况比较玄学,不一定每个都会乱码。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Titletitle>
head>
<body>
<form method="post" action="/e/t1">
<input type="text" name="text">
<input type="submit">
form>
body>
html>
@RequestMapping("/e/t1")
public String test2(String text, Model model) throws Exception {
System.out.println("test1: "+text);
model.addAttribute("msg",text);
return "hello";
}
可以看到后端拿到数据就已经乱码了,在接受流解析之前就已经乱码。最后响应给客户端的也乱码。
所有的乱码问题大多数都是因为接受解析的时候乱码的,其他的情况只需要简单设置即可。而且post、get请求是不一样的,tomcat8之后设置了为utf-8编码集。get请求是不会乱码的,post的请求会,以下主要针对post请求解决编码问题!
在controller类接受参数/响应之前经过一下HttpServletRequest、HttpServletResponse,先设置编码集,再获取参数就OK了。
@RequestMapping("/e/t2")
public String test2(HttpServletRequest req, HttpServletResponse resp, Model model) throws Exception {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
String text = req.getParameter("text");
System.out.println("test2: "+text);
model.addAttribute("msg",text);
return "hello";
}
一般情况下这种Controller太多了,一般会设置一个过滤器用于过滤所有的请求!这种是比较常用的方式。注意Filter接口是javax.servlet包下的filter。
import javax.servlet.*;
import java.io.IOException;
public class EncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=UTF-8");
chain.doFilter(req, resp);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
并且在web.xml中配置一下过滤所有的请求,注意" / " 和 " /* “的区别。” / “不会过滤jsp页面,” / * " 会过滤所有的请求包括页面。
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*
MVC过滤器底层封装好了,只需要在Web.xml中配置一下即可;不用手写过滤器与第二种方式没有什么区别…
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>