返回地图的春季 MVC @ResponseBody会产生"Error 406 NOT ACCEPTABLE"



我有一个问题,试图设置@ResponseBody返回一个集合。我在类路径中有JAXB jar,并且我没有设置任何ContentNegotiatingViewResolver。

这是我的简单对象:-

@XmlRootElement(name = "test-object")
@XmlAccessorType(XmlAccessType.FIELD)
public class TestObject implements Serializable {
    @XmlAttribute
    private int id;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
}

我写了一个简单的测试,返回一个对象…这可以正常工作,并且我可以看到生成的XML:-

@RequestMapping(value = "one", method = RequestMethod.GET)
public @ResponseBody TestObject getSingleObject() {
    TestObject obj = new TestObject();
    obj.setId(1);
    return obj;
}

我真正想要的是返回一个对象列表。仔细阅读后,似乎这样做的方法是将列表放在映射中并返回映射:-

@RequestMapping(value = "all", method = RequestMethod.GET)
public @ResponseBody Map<String, ? extends Object> getAllObjects() {
    TestObject obj1 = new TestObject();
    obj1.setId(1);
    TestObject obj2 = new TestObject();
    obj2.setId(2);
    List<TestObject> list = Arrays.asList(obj1, obj2);
    return Collections.singletonMap("all-objects", list);
}

当我执行上面的命令时,我得到"Error 406 Not Acceptable"。

我在这里做错了什么?如果有区别的话,我使用的是Jetty 6.1。

谢谢。

您需要在pom.xml中添加这两个依赖项!

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-lgpl</artifactId>
    <version>1.8.1</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-lgpl</artifactId>
    <version>1.8.1</version>
</dependency>

我遇到了同样的问题,经过几个小时的调试,我终于找到了解决方案。为了防止别人遇到同样的问题,以下是我的发现。

您可能遵循了Spring 3中的Ajax简化,它告诉您使用mvc:注释驱动的配置元素。

它没有告诉你的是mvc:注解驱动只是一个定义几个标准bean的快捷方式,除非你已经定义了这些bean中的一个!

在mvc:注解驱动的配置中,MappingJacksonHttpMessageConverter被注册为org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.

如果你已经定义了自己的AnnotationMethodHandlerAdapter,你也应该手动定义这个MappingJacksonHttpMessageConverter。

Cfr不使用notationmethodhandleradapter注册的自定义消息转换器,只使用默认的消息转换器。它讨论了一个类似的问题。另外检查一下SPR-6524和SPR-6306,由于垃圾邮件预防,不能发布链接:(

我的spring配置中的相关部分最终看起来像这样:

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="webBindingInitializer">
            <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
                <property name="validator">
                    <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
                    </bean>
                </property>
            </bean>
        </property>
         <property name="messageConverters">
            <list>   
                <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.feed.AtomFeedHttpMessageConverter"/>
                <bean class="org.springframework.http.converter.feed.RssChannelHttpMessageConverter"/>
            </list>
        </property>
</bean>

我知道这个问题有点老了,但是我也遇到过同样的问题。

我解决了添加到构建路径两个jar: jackson-core-asl-1.x.jarjackson-mapper-asl-1.x.jar。你可以从这里下载它们:http://wiki.fasterxml.com/JacksonDownload或者如果你使用Maven,你可以将它们添加为项目依赖项。

注意,我使用的是版本1。x(在我的例子中是1.9)而不是2.x。

更多的建议而不是答案,但是您是否尝试过创建地图,然后添加对象,然后像这样返回地图?

@RequestMapping(value = "all", method = RequestMethod.GET)
public @ResponseBody Map<String, ? extends Object> getAllObjects() {
    TestObject obj1 = new TestObject();
    obj1.setId(1);
    TestObject obj2 = new TestObject();
    obj2.setId(2);
    List<TestObject> list = Arrays.asList(obj1, obj2);
    Map<String, Object> map = new TreeMap<String, Object>();
    map.put("all-objects",list);
    return map;
}

相关内容

最新更新