莫名其妙的400问题

504 阅读2分钟

故事背景

某次开心的写完一段代码后,进入了前后端联调阶段,眼看需求提测在即,突然前端发来条消息说:“接口报错,400了!” 我心想肯定又是前端不守规矩乱调接口了,便回复道:“好好检查一下,我这边swagger上测过的。”

10分钟后,前端又发来了消息:“没问题啊我这。”还发来了他的DevTools截图,力证清白。400 bad request,我眉头一皱,发现事情没有那么简单。

我打开fiddler,分别使用swagger和前端界面操作了两次,然后将两次请求的完整session拷贝出来,使用在线文本比对工具对比了下,尼玛没有什么不同啊。再仔细瞧瞧,似乎多出一个入参字段来,会是这玩意导致的?

抱着试试看的心态,我编辑了下这个请求,去掉多出的字段,retry了一下,果不其然,通了!还有这样的事?

正要查查原因,pm发消息要聊新需求,再看下消息列表,测试问啥时候提测、客诉群@我排查问题、一个外部门的哥们问某某接口文档地址……算了,下次再查吧。于是回复前端:“把那个xxx字段去掉。”

时光荏苒,两三个月过去了,"又400了!“前端又喊起来。我心想又搞事,便回复:"是不是又有多余字段?"前端虽然回复是,但不耐烦于总要发送请求前修剪入参。虽然前端给后端多传一堆垃圾字段过来不是什么好事,但我也疲于跟他们掰扯了。嗯,是时候查下原因了。

原因排查

SpringMVC默认使用的是jackson,默认不允许出现bean中未知的字段,配置一下FAIL_ON_UNKNOWN_PROPERTIES=false就好了。

解决方法

SpringMVC用的是MappingJackson2HttpMessageConverter这个类,可以通过继承ObjectMapper来重写默认配置,来为其设置新的转换规则。

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

public class MyObjectMapper extends ObjectMapper {
    public MyObjectMapper() {
        super();
        // 当前端传入json包含未知字段时,不抛异常(默认值为true)
        this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }
}

修改spring配置:

    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="false">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>application/json;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
                <property name="objectMapper">
                <!--这里设置为自定义的objectMapper,覆盖默认设置-->
                    <bean class="com.cafeboy.common.MyObjectMapper"></bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

后记

修改过配置后,前端再也没有找过我排查400的问题。嗯,世界又清静了一点点……