一尘不染

Spring-MVC 406不可接受,而不是JSON响应

spring

我正在尝试使用Spring 3.0.6返回JSON响应,但是得到了406响应“ Not Acceptable”,其描述为:“此请求所标识的资源仅能够生成具有以下特征的响应:请求“接受”标头()。”

我知道之前曾问过一个非常类似的问题,但尽管进行了许多测试,但我无法使它适用于我的项目,而且我不知道自己在做什么错。

在我的Maven pom.xml中,执行以下操作:

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
  <version>1.8.5</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-core-asl</artifactId>
  <version>1.8.5</version>
  <scope>compile</scope>
</dependency>

在web.xml中,我引用了webmvc-config.xml,并且日志确认已加载。

<servlet>
    <servlet-name>mainServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/webmvc-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

在webmvc-config.xml中,我具有以下内容:

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
    </bean> 
    <mvc:annotation-driven />

我的控制器是:

@Controller
public class ClassifiedController {

    @RequestMapping(value = "/classified/{idClassified}", headers = "Accept=*/*",
                    method = RequestMethod.GET)
    @ResponseBody
    public final Classified getClassified(@PathVariable final int idClassified) {
        ...

我尝试使用或不使用headers参数,结果相同。如果我直接使用Firefox调用URL,则请求标头包含以下内容(已通过Firebug选中):

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

如果我使用以下JQuery:

$.ajax({
        url: '/classified/38001',
        type: 'GET',
        dataType: 'json'
});

发送以下标头:

Accept: application/json, text/javascript, */*; q=0.01

在这两种情况下,结果都是406错误。我不知道还要检查什么才能使其正常工作。

更新:我决定通过Spring调试,发现在杰克逊被正确调用,并且在org.codehaus.jackson.map.ser.StdSerializerProvider中,方法_findExplicitUntypedSerializer包含以下代码:

try {
    return _createAndCacheUntypedSerializer(runtimeType, property);
} catch (Exception e) {
    return null;
}

这很不幸,因为隐藏了问题的根源。使用调试器,我发现该异常包含非常描述性的错误消息:

Conflicting getter definitions for property "reminded": 
ClassifiedImpl#isReminded(0 params) vs
ClassifiedImpl#getReminded(0 params)

现在,我看到了错误消息,这是一个愚蠢的错误,很容易修复,但如果没有它,它并不是那么明显。实际上,解决问题导致序列化工作。


阅读 449

收藏
2020-04-18

共2个答案

一尘不染

就MappingJacksonJson处理而言,你需要确保Jackson ObjectMapper支持你的对象类型进行序列化。

2020-04-18
一尘不染

在DispatcherServlet-servlet.xml中添加以下内容。

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jacksonMessageConverter"/>
        </list>
    </property>
</bean>
2020-04-18