Spring MVC:@ResponseBody,415不支持的媒体类型

时间:2011-08-22 17:15:22

标签: hibernate spring-mvc jackson

我无法将JSON帖子映射到特定的Java对象,以通过 Hibernate

保存它

正确设置了Ajax调用的标头...

Accept          application/json
Content-Type    application/json; charset=UTF-8

,HTTP-Method为 POST

这是我的配置......

My Spring MVC功能映射看起来像这样

@RequestMapping(value = {"/save.json"},method = RequestMethod.POST)
public ModelMap save(@RequestBody Seizure seizureObj,Model model) {
   ...
}

在我的容器xml中我有 ContentNegotiatingViewResolver 这样的

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="mediaTypes">
        <map>
            <entry key="html" value="text/html" />
            <entry key="json" value="application/json" />
        </map>
    </property>
    <property name="viewResolvers">
        <list>
            <bean id="viewResolver"
                class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                <property name="prefix" value="/WEB-INF/assets/" />
                <property name="suffix" value=".jsp" />
            </bean>
        </list>
    </property>
    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                <property name="prefixJson" value="false" />
                <property name="objectMapper" ref="jacksonObjectMapper" />
            </bean>
        </list>
    </property>
</bean>

在我的容器xml中杰克逊的部分

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapterConfigurer"
    init-method="init">

    <property name="messageConverters">
        <list>
            <bean id="marshallingHttpMessageConverter"
                class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"
          >
          <property name="objectMapper" ref="jacksonObjectMapper" />
          </bean>
        </list>
    </property>
</bean> 

<bean id="jacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" /> 

我有

  • 杰克逊核-ASL-1.8.5
  • 杰克逊映射器-ASL-1.8.5

在我的/ lib文件夹中

杰克逊正在为这样一个简单的案件工作

public class Simple {
  private int id;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }   
}

@RequestMapping(value = {"/saveSimple.json"},method = RequestMethod.POST)
public ModelMap save(@RequestBody Simple simple,Model model) {
   ...
}

当我用curl测试它时

 curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":1}'  http://<URL>/saveSimple.json

没问题,但如果我用Hibernate对象测试它,我会得到消息

415 Unsupported Media Type

任何想法。

4 个答案:

答案 0 :(得分:13)

StanMax带领我走向正确的方向......

首先,我必须设置@JsonManagedReference@JsonBackReference权利。我将ManagedReference设置为表示 ONE-to-MANY 关系的 ONE 的属性,但显然您必须将其设置为 MANY 属性(集合)

请参阅此处的说明 http://wiki.fasterxml.com/JacksonFeatureBiDirReferences

  

@JsonBackReference是引用的“后退”部分:它将从序列化中省略,并在反向引用的反序列化过程中重新构建。

     
      
  • 带注释的属性必须是bean类型
  •   

我的问题是我在JSON POST中没有发送足够的信息来满足Hibernate的要求。

这导致了一个异常,即从我的JSON POST中创建Hibernate对象的正确字段不存在。

我创建了一个测试网址,我自己创建了Object mapper,并尝试手动反序列化JSON。抛出正确的错误信息。

在我看来,Spring不幸抛出415“不支持的媒体类型”例外,这有点误导。

所以对未来而言。首先手动尝试(参见示例),然后再继续。

 ModelMap map = new ModelMap();
 logger.info("HibernateAware");
 HibernateAwareObjectMapper mapper = new HibernateAwareObjectMapper();
 String jsonInput = 
 "{" +
   "\"id\":\"1\"," +
   "\"matCountry\":{" +
     "\"id\":\"1\"" +
   "}" +
 "}";
 Seizure seizure = mapper.readValue(jsonInput, Seizure.class); // this line throw the exception

希望这有助于某人。

问候JS

答案 1 :(得分:4)

您可以尝试的一件事是弄清楚问题是否与Jackson的数据绑定(无法序列化hibernate对象)或其他问题有关。这可以通过手动构造ObjectMapper来完成,检查'mapper.serializeValueAsString()'是否有效或抛出异常。

很有可能与杰克逊处理懒惰的物业有关;如果是这样,您可能需要使用jackson hibernate module,因为它可以处理特定于Hibernate的详细信息。

答案 2 :(得分:2)

我遇到了同样的问题。在阅读了MappingJacksonHttpMessageConverter的工作原理之后,我意识到我没有正确地初始化它。 所以我在rest-servlet.xml中使用了以下内容,它起作用..

<bean id="jsonHttpMessageConverter"  class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
    <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json" />
        </map>
    </property>

    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
                <property name="objectMapper">
                    <ref bean="JacksonObjectMapper" />
                </property>
            </bean>
        </list>
    </property>
    <property name="favorPathExtension" value="false" />
    <property name="favorParameter" value="true" />
    <property name="useNotAcceptableStatusCode" value="true" />
</bean>

<bean id="JacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />

答案 3 :(得分:0)

我有一个类似的问题,这是由于我的一个班级的地图具有非原始键类型。我能够@JsonIgnore到此字段来解决此问题。