2011-08-22 100 views
6

我无法通过映射JSON后到一个特定的Java对象,以保存休眠Spring MVC的:@ResponseBody,415不支持的媒体类型

Ajax调用的页眉设置是否正确?

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

和HTTP的方法是POST

这里谈到我的配置...

我的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 -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"id":1}' http://<URL>/saveSimple.json 
测试个

没有问题,但如果我使用Hibernate的对象测试我得到的消息

415 Unsupported Media Type 

任何想法。

回答

13

StanMax导致我在正确的方向...

首先我必须设置@JsonManagedReference@JsonBackReference权。我设置了ManagedReference到代表的ONE一对多关系ONE属性,但显然你必须将其设置为MANY属性(集合)

看到这里的描述 http://wiki.fasterxml.com/JacksonFeatureBiDirReferences

@JsonBackReference是参考“背”部分:它将从串行化被省略,并且的前向参考反序列化期间重新构成。

  • 注释属性必须是bean类型

的在我的情况的问题是,我没有在我的JSON POST匹配Hibernate的要求发送足够的信息。

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

我创建了一个测试网址,我自己创建了对象映射器,并试图手工反序列化JSON。这会抛出正确的错误信息。

在我看来,春天遗憾地抛出了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

+0

这完全节省了我的一天......一周。确实误导错误信息的确如此!这怎么可能? –

+0

呵呵我希望你upvoted;) –

+0

+1 - 真棒调试技巧。 – Martin

4

你可以尝试的一件事是找出问题是否与杰克逊的数据绑定(无法序列化hibernate对象)或其他东西。这可以通过手动构建ObjectMapper来完成,检查'mapper.serializeValueAsString()'是否工作或引发异常。

这是一个很好的机会,它与杰克逊处理懒惰加载的属性有关;如果是这样,您可能需要使用jackson hibernate module,因为它可以处理Hibernate特定的细节。

+0

我得到错误信息''“defaultReference”:反向引用类型(java.util.Set中)与托管类型不兼容()'' –

2

我有同样的问题。在阅读了MappingJacksonHttpMessageConverter的工作方式后,我意识到我没有正确初始化它。 所以我用我的休息-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" /> 
相关问题