笔者近日遇到了SpringMVC框架POST提交中文乱码的问题。显示html特殊字符命名实体(https://www.cnblogs.com/yesw/p/4380442.html)。
对此进行了调查,解决方法在网上有很多,在此进行总结。
在SpringMVC框架下,解决中文提交乱码的问题,首先要保证页面设定的form的字符编码是UTF-8格式。
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
其次,Servlet服务器实现的Servlet遇到URL和POST提交的数据,它会按照指定的字符集解码。这里所说的"指定的字符集"是在应用服务器的配置文件中配置。对于tomcat服务器,该文件是server.xml中的Connector节点指定URIEncoding="UTF-8"。对Get方式的乱码问题,由于参数是通过URL传递的,因此这一设定非常有效。
做到以上两点,可能仍然不会解决post方式提交的请求的乱码的问题。原因是Servlet 3.0规范中有关请求数据编码做了如下解释:
当前很多浏览器并不发送带Content-Type头部的字符编码标识符,它会把字符编码的决定留在读取HTTP请求的时候。如果客户端没有指明编码,容器用来创建请求读和解析POST数据的默认编码必须是"ISO-8859-1"。然而,为了提示开发者客户端没有成功发送一个字符编码,容器中getCharacterEncoding方法会返回null。
如果客户端没有设置字符编码,并且请求数据使用了不同编码而不是上述的默认编码,程序将会出现中断。为了纠正这种状态,一个新的方法setCharacterEncoding(String enc) 被添加到ServletRequest接口。开发者调用这个方法能重写容器提供的字符编码。这个方法必须在解析request中任何post数据或者读任何输入之前调用。一旦数据已经被读取,调用这个方法不会影响它的编码。
再回到springMVC框架,因为框架默认没有指定按何种字符集对request的内容进行解码,CharacterEncoding默认为"",所以会发生乱码问题。
为解决这个问题,当request中的post数据被读取了的情况下,比如controller层,可以采用
new String(request.getParameter("XXXX").getBytes("iso-8859-1"), "utf-8")的方式进行强制解码。
或者在request读取post数据之前,手动设置数据读取的编码格式:request.setCharacterEncoding("utf-8");
当然Spring已经提供了现成的编码过滤器。在Web.xml中增加如下配置(要注意的是它的位置一定要是第一个执行的过滤器,否则可能不会生效)即可:
<filter>
<filter-name>charsetFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>