【问题标题】:JSON Mapping in my Spring MVC 3.2 Application Works for Only One of My Methods我的 Spring MVC 3.2 应用程序中的 JSON 映射仅适用于我的一种方法
【发布时间】:2013-05-19 21:59:35
【问题描述】:

我正在开发一个 Spring 3.2 MVC 应用程序。它的设置相当典型,但我的问题是当我尝试从控制器方法返回 JSON 对象时收到 406 状态错误。

令人沮丧的是,除了我的一种方法之外,我从服务器获得了响应。我包含的代码是我在网上找到的修改后的 Spring MVC json 示例。带有路径变量的示例控制器方法按预期工作,但我添加到控制器的其他方法没有。

我对示例代码所做的唯一其他更改发生在 pom.xml 中。我将jackson依赖升级到最新版本。

那么我错过了什么?我的类路径上有杰克逊映射器罐子。我在我的 servlet 中使用了 <mvc:annotation-driven /> 指令,并且在我的每个控制器方法中都使用了 @ResponseBody 注释。

任何帮助将不胜感激!

调度程序 servlet:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="uk.co.jeeni" />

    <mvc:annotation-driven />

    </beans>

pom.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
     xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<modelVersion>4.0.0</modelVersion>

<groupId>uk.co.jeeni</groupId>
<artifactId>spring-json</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>

<name>Spring 3 MVC JSON Example</name>

<properties>
    <spring.version>3.2.1.RELEASE</spring.version>
</properties>

<dependencies>
    <!--
      Jackson mapper is used by spring to convert
      Java POJOs to JSON strings.
    -->
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-mapper-asl</artifactId>
        <version>1.9.12</version>
    </dependency>

    <!-- START: Spring web -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

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

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- END: Spring web -->
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.5</source>
                <target>1.5</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.1</version>
        </plugin>
  </plugins>
    <finalName>spring-mvc-json</finalName>
</build>

控制器:

    package uk.co.jeeni;

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;


    @Controller
    public class JsonService {

    private static Map<String, Person> data = new HashMap<String, Person>();
    static{
    data.put("ADAM", new Person("Adam", "Davies", 42));
    data.put("JANE", new Person("Jane", "Harrison", 35));
    }

    @RequestMapping(value="{name}", method = RequestMethod.GET)
    public @ResponseBody Person getPerson(@PathVariable String name){
    Person p = new Person(name, name, 105);//data.get(name.toUpperCase());
    return p;
    }


@RequestMapping(value="/testJson.html", method=RequestMethod.GET)
public @ResponseBody List<Person> testJson()
{
    List<Person> people = new ArrayList<Person>();

    for(int i=0;i<10;i++)
    {
        Person p = new Person("Firstname", "Lastname", i);
        people.add(p);
    }

    return people;
}

@ResponseBody
@RequestMapping(value="testJsonPojo.html", method=RequestMethod.GET)
public Person testJsonPojo()
{
    Person individual = new Person("Firstname", "Lastname", 105);

    return individual;
}
}

Person.java:

    package uk.co.jeeni;

    public class Person {
    private String firstName;
    private String lastName;
    private int age;

    public Person(String firstName, String lastName, int age) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
    }

    public String getFirstName() {
    return firstName;
    }

    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }

    public String getLastName() {
    return lastName;
    }

    public void setLastName(String lastName) {
    this.lastName = lastName;
    }

    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }
}

【问题讨论】:

  • 哪个不行?另外,你用的是什么客户端?浏览器,ajax?
  • @SotiriosDelimanolis 我的客户是 firefox,尽管我也使用 ajax 对其进行了测试。使用路径变量的方法有效。其他人没有。
  • 尝试使用 java 客户端(使用 URLConnectionHttPClient)向应用程序发出请求,但将 Accept 标头设置为 application/json。由于unacceptable contents 而发生 HTTP 406 错误
  • @SotiriosDelimanolis 好的...我可以尝试一下,但这并不能解释为什么我的一种方法可以按我的预期工作,而其他方法却不能。

标签: json spring maven spring-mvc jackson


【解决方案1】:

不工作的方法的映射 URL 以 .html 结尾。这没有任何意义,因为您正在返回 JSON 数据。我建议您更改映射:

@RequestMapping(value="/testJson.json", method=RequestMethod.GET)

由于扩展,Spring将请求的媒体类型设置为html,所以不会转发到JSON视图。

【讨论】:

  • 感谢您回答我的问题。映射的扩展不应影响服务器的响应。我在其他项目中使用了 .html 扩展名。这些项目被配置为映射到任何带有 .html 扩展名的东西。所以我认为在这种情况下也不是问题,但它很简单,我可以尝试一下,这样我就可以完全排除它。
  • 我做了一个示例项目,我观察了答案中的行为。也许那些其他项目的配置不同?看这里:blog.eyallupu.com/2009/07/…
  • 我看到你没有使用ContentNegotiatingViewResolver。划掉最后一条评论。
  • 我删除了 .html 并删除了 406 错误。谢谢!我仍然不确定为什么会这样,因为我在其他 Spring 项目中使用了 .html 和我的响应正文映射。
【解决方案2】:

这可能是您在 3.2 中引入的 mvc:annotations 的问题,此处已得到解答:

https://stackoverflow.com/a/13939290/3014094

在 Spring 3.2 中需要对 mvc:annotations 进行额外的更改。它试图根据请求的扩展自动分配媒体类型。我猜它可能是 /doSomething.html 没有映射到 JSON。

更新您的 mvc spring 配置以关闭此自动映射

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />
<bean id="contentNegotiationManager"
    class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <!-- Turn off working out content type based on URL file extension, should 
        fall back to looking at the Accept headers -->
    <property name="favorPathExtension" value="false" />
</bean>

【讨论】:

    猜你喜欢
    • 2017-05-13
    • 1970-01-01
    • 2017-09-28
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    相关资源
    最近更新 更多