Spring MVC 中的错误 406 - 从 Spring 3.0.5 迁移到 Spring 4.2.4



我正在将Web应用程序从Spring 3.0.5迁移到4.2.4。经过许多障碍(显然这个过程并没有真正记录下来......),我遇到了可怕的406错误。似乎有很多问题,但没有一个答案是有效的(即使是有问题的)。

这是带有以下函数的控制器代码:

@Controller
public class TestController {
@RequestMapping(value = "/echo", method = RequestMethod.GET, headers = "Accept=*/*")
@ResponseBody
public String echoReply(HttpServletRequest request) throws Exception {
    return "echo";
}
@RequestMapping(value = "/test", method = RequestMethod.GET, headers = "Accept=*/*")
@ResponseBody
public boolean testFunc(HttpServletRequest request) throws Exception {
    ...
    return ...;
}

第一个函数按预期返回echo,但测试函数返回错误 406 - Could not find acceptable representation 。确切的消息是:

The resource identified by this request is only capable of generating
responses with characteristics not acceptable according to the request
"accept" headers

两者都与 AJAX 调用和通过 URL 直接访问相关。

任何想法要寻找什么以及为什么会这样发生?

编辑:也许这是控制器类注释中的一些问题(Spring 4.2 中应该缺少的东西)?

应用上下文.xml

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:mvc="http://www.springframework.org/schema/mvc"
   xmlns:tx="http://www.springframework.org/schema/tx"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd
     http://www.springframework.org/schema/mvc
     http://www.springframework.org/schema/mvc/spring-mvc.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop.xsd" default-lazy-init="true">
    <context:annotation-config />
    <aop:aspectj-autoproxy />
    <tx:annotation-driven/>
    <mvc:annotation-driven/>
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
       <property name="persistenceUnitName" value="..." />
    </bean>
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
    // bunch of component-scans and some more beans
</beans>

绒球.xml:(杰克逊的相关依赖关系)

    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>1.9.13</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.7.1-1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.7.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.7.1</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-base</artifactId>
        <version>2.7.1</version>
    </dependency>

Spring MVC 官方文档将以下数据类型列为控制器方法的有效返回类型:

  • ModelAndView
  • Model
  • Map
  • View
  • String
  • void
  • HttpEntity
  • HttpHeaders
  • Callable
  • DeferredResult
  • ListenableFuture
  • ResponseBodyEmitter
  • SseEmitter
  • StreamingResponseBody

对于用 @ResponseBody 批注的控制器方法,返回类型将写入响应正文。 此过程使用适用于Accepts请求标头的HttpMessageConverter执行。


由于您的testFunc方法的返回类型为 boolean ,Spring MVC 将尝试使用 HttpMessageConverter 写入返回值。 这意味着,Accepts标头必须指定一个值,该值将导致boolean值的有效表示形式。 因此,表示形式只能是无架构的,例如 JSON。 任何其他表示都将导致所描述的错误。

因此,如果Accepts标头设置为 text/htmlapplication/xmlboolean将无法写入响应正文。 但是,如果您将标头设置为 application/json ,您的boolean值将被正确写入。

如果还想支持 HTML 和 XML,则必须将boolean包装在对象(如 Map 或自定义对象)中。

尝试使用 更新app-context.xml

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>

最新更新