SpringMVC中获取请求消息乱码的正确解决姿势

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 查看本文章
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}

猜你喜欢

转载自blog.csdn.net/asdfjklingok/article/details/119840036