2

我的问题是我想使用 Spring MVC 和随附的标准注释将 Java 集合作为 JSON 返回。不幸的是,虽然我每次都得到 HTTP 错误代码 406。

“此请求标识的资源只能生成具有根据请求“接受”标头不可接受的特征的响应。”

我认为 Jackson 和 Spring 可以自动转换我的返回类型,但如果我们使用集合或任何其他返回类型而不是String. 你能帮我看看我做错了什么吗?


研究
正如我所提到的,我们可以返回一个字符串。我们认为问题出在 Maven(与 Jackson 的依赖关系)中,或者出在我们对 Spring MVC REST 注释的理解中。另一条路线是我们没有正确配置我们的 Spring 上下文。


控制器
这是我带注释的 Spring 控制器。第一个简单方法 ( getAJsonString) 有效,但第二个 ( getImprovedJsonMap) 使用映射返回 HTTP 错误代码 406,我们认为这是由于复杂类型:

@Controller
@RequestMapping("/kfc/brands")
public class DefaultMetricsService {

    @RequestMapping(value="/firstMethod", method = RequestMethod.GET)
    public @ResponseBody String getAJsonString() {
        return "HELLO";
    }

    @RequestMapping(value = "/Metrics/type3", method = RequestMethod.GET)
    public @ResponseBody Map<String, String> getImprovedJsonMap() {
        Map jsonMap = new HashMap<String, String>();
        jsonMap.put("counter", "3000");
        return jsonMap;
    }


Spring Servlet 定义
这是我的 Spring 配置(metrics-servlet.xml

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

    <context:component-scan base-package="com.t2" />

    <mvc:annotation-driven />


</beans>
...



这是我的杰克逊版本的pom

<!-- Dependency Versions -->
    <org.slf4j.version>1.6.1</org.slf4j.version>
    <spring.version>3.2.2.RELEASE</spring.version>
    <commons.loggin.version>1.1.1</commons.loggin.version>
    <junit.version>4.8.2</junit.version>
    <jackson.version>1.9.10</jackson.version>    

 ...
        <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
        <exclusions>
            <!-- Exclude Commons Logging in favor of SLF4j -->
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>${commons.loggin.version}</version>
    </dependency>

    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.6</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    <!-- Jackson JSON Mapper -->
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>${jackson.version}</version>
    </dependency>

    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-core-asl</artifactId>
        <version>${jackson.version}</version>
    </dependency>
...


Servlet
这是我的 servlet 定义:

    <servlet>
    <servlet-name>metrics</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:metrics-application-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>metrics</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:metrics-servlet.xml</param-value>
</context-param>

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>
4

3 回答 3

2

我认为您可能在 Spring 3.2 中遇到内容协商问题。请参阅Spring 文档

尝试在您的metrics-servlet.xml

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
</bean>
于 2013-09-19T09:11:13.237 回答
1

看起来您还没有在 spring 上下文中初始化 Jackson 序列化程序。

尝试将以下行添加到您的 metrics-servlet.xml:

    <bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</beans>

仅供参考,我的 spring servlet 使用的是 mvc、bean 和 context 版本 3.2。

希望这可以帮助!

于 2013-09-19T20:54:10.870 回答
0

您需要添加produces="application/json"到您的@RequestMapping,以便将响应标识为 JSON。

@RequestMapping(value = "/Metrics/type3", method = RequestMethod.GET, produces="application/json")
于 2013-09-19T09:13:53.000 回答