SpringMVC中获取请求消息乱码解决办法–正确的姿势以及原理分析
小明想将前端页面的表单中的数据传递给后台,前端写了个form表单
<form th:action="@{/getPhone}" th:method="post">
name:<input type="text" name="name">
<br>
price:<input type="text" name="price">
<input type="submit" name="表单内容传递给对象">
</form>
使用 SpringMVC 控制器方法 getPhone 接收请求参数
使用 SpringMVC 控制器方法 getPhone 接收请求参数
@RequestMapping("/getPhone")
public String getPhone(Phone phone){
System.out.println(phone);
return "succ";
}
一顿犀利的操作之后发现传递到服务器的数据乱码了
Phone{name=’?°???’, price=100.0}
小明想了个办法
@RequestMapping("/getPhone")
public String getPhone(Phone phone, HttpServletRequest request) throws UnsupportedEncodingException {
request.setCharacterEncoding("utf-8");
System.out.println(phone);
return "succ";
}
既然IoC容器里有request对象,那么可以自动将request注入到getPhone的形参中,这时候再设置下编码,然后取请求参数,就不会乱码了。
想法对、逻辑也似乎对, 小明继续发送form表单数据,服务端发现:
Phone{name=’?°???’, price=100.0}
小明心情不美丽了,心理一直在想 是不是没生效? 是不是服务器没部署? 是不是… ?
我们知道, SpringMVC是基于原生的Servlet,通过了功能强大的前端控制器 DispatcherServlet,对请求和响应进行统一处理
Servlet中,设置字符编码是在request请求参数获取之前,如果获取过请求参数, 那么再设置字符编码,就无效了。
“比如小明妈妈去菜市场买菜, 萝卜标价1元一斤, 等挑选好萝卜,称好,结算的时候, 卖萝卜的老大爷说萝卜两元一斤。小明的妈妈只能给他1元…”
最开始没设置字符集, 服务器都按默认字符集解析好了数据,你突然来说字符集不对,你要UTF-8的, 你是找“抽”类型的?
小明老老实实在web.xml 中配置了过滤器,添加了字符集, 保证了请求参数获取之前设置好字符集。
<filter>
<filter-name>characterEncodingFilter</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>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
我们看一下SpringMVC中的编码过滤器:
扫描二维码关注公众号,回复:
13419656 查看本文章
![](/qrcode.jpg)
public class CharacterEncodingFilter extends OncePerRequestFilter {
@Nullable
private String encoding;
private boolean forceRequestEncoding;
private boolean forceResponseEncoding;
public CharacterEncodingFilter() {
this.forceRequestEncoding = false;
this.forceResponseEncoding = false;
}
...
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String encoding = this.getEncoding();
if (encoding != null) {
if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
request.setCharacterEncoding(encoding);
}
if (this.isForceResponseEncoding()) {
response.setCharacterEncoding(encoding);
}
}
将SpringMVC 控制器方法还原
@RequestMapping("/getPhone")
public String getPhone(Phone phone) {
System.out.println(phone);
return "succ";
}
再次获取参数
Phone{name=‘小明’, price=100.0}