Spring MVC框架下406错误解析

Spring MVC框架下406错误解析

报错如下:
这里写图片描述

这里产生的场景一般是你使用@ResponseBody,希望把后台的model转换成其他的格式如(json/xml)返回给前台。下面我们以返回json格式为例,浅析一下原理,然后分析一下可能出现的问题以及处理方法。

原理浅析

1. 注册消息转换器MappingJackson2HttpMessageConverter

我们都知道,spring mvc会自动帮我们注册消息转换器MappingJackson2HttpMessageConverter用来把model返回成json,注册是由类AllEncompassingFormHttpMessageConverter完成的,其构造函数如下:

public AllEncompassingFormHttpMessageConverter() {
        addPartConverter(new SourceHttpMessageConverter<Source>());

        if (jaxb2Present && !jackson2XmlPresent) {
            addPartConverter(new Jaxb2RootElementHttpMessageConverter());
        }

        if (jackson2Present) {
            addPartConverter(new MappingJackson2HttpMessageConverter());
        }
        else if (gsonPresent) {
            addPartConverter(new GsonHttpMessageConverter());
        }

        if (jackson2XmlPresent) {
            addPartConverter(new MappingJackson2XmlHttpMessageConverter());
        }
    }

通过构造函数我们可以看出,只要jackson2Present为true,spring就会自动帮我们注册MappingJackson2HttpMessageConverter,我们再来看一下jackson2Present

private static final boolean jackson2Present =
            ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", AllEncompassingFormHttpMessageConverter.class.getClassLoader()) &&
                    ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", AllEncompassingFormHttpMessageConverter.class.getClassLoader());

只要类加载器中有ObjectMapper,JsonGenerator这两个类,jackson2Present 就会为true。从这里,我们看到,一定要引入jackson的jar包才能注册MappingJackson2HttpMessageConverter

2. AllEncompassingFormHttpMessageConverter初始化

从刚才的分析中我们知道了AllEncompassingFormHttpMessageConverter初始化的时候会注册消息转换器,那么AllEncompassingFormHttpMessageConverter初始化又发生在什么地方呢?
通过搜索,我们得知,AllEncompassingFormHttpMessageConverter发生的地方有很多,在这里只能是RequestMappingHandlerAdapter中,其构造函数如下:

public RequestMappingHandlerAdapter() {
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
        stringHttpMessageConverter.setWriteAcceptCharset(false);  // see SPR-7316

        this.messageConverters = new ArrayList<HttpMessageConverter<?>>(4);
        this.messageConverters.add(new ByteArrayHttpMessageConverter());
        this.messageConverters.add(stringHttpMessageConverter);
        this.messageConverters.add(new SourceHttpMessageConverter<Source>());
        this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
    }

很明显,在构造函数中初始化了AllEncompassingFormHttpMessageConverter,我们都知道RequestMappingHandlerAdapter 在使用了annotation-driven后自动注册。 所以,这就要求我们在dispatcherServlet的配置文件中不要忘了<mvc:annotation-driven />

错误排查

通过分析上面的原因,错误的地方已经很容找到了。

1. 检查dispatcherServlet的配置文件 dispatcher-servlet.xml

一定要有<mvc:annotation-driven />
并且注意检查命名空间是否配置错误,命名空间里要有对应的mvc配置

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        **http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd**">

2. 检查有没有引入jackson相关的包

由于maven是自动依赖,在pom.xml中只需要引入jackson-databind即可

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.9</version>
        </dependency>

3. 有没有在controller方法返回体上使用@ResponseBody注解

    @ResponseBody
    public UserBean getUser() {
        UserBean userBean = userService.getUser(1);
        return userBean;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值