【问题标题】:Adding Jaxb2 message converter in Spring breaks Jackson2 json mapping在 Spring 中添加 Jaxb2 消息转换器休息 Jackson2 json 映射
【发布时间】:2013-09-10 02:45:21
【问题描述】:

我正在努力让我的 Spring rest 应用程序可以同时处理 xml 和 json 响应,但似乎添加 Jaxb 消息转换器破坏了我的 json 映射。

@Bean
public MappingJackson2HttpMessageConverter jsonConverter() {
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addSerializer(String.class, new StringSerializer());
    ObjectMapper mapper = new ObjectMapper()
        .registerModule(simpleModule);
    converter.setObjectMapper(mapper);
    return converter;
}

@Bean
public Jaxb2RootElementHttpMessageConverter jaxbConverter() {
    return new Jaxb2RootElementHttpMessageConverter();
}

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.add(jsonConverter());
    converters.add(jaxbConverter());
}

如果我在这里注释掉第二个和第三个方法,一切都会重新开始工作(当然除了 xml 映射!)。但是,有了这些,我就搞砸了,比如将List&lt;String&gt; 序列化为[APPLEORANGEBANANA],其中apple、orange 和banana 在列表中是单独的字符串。

如果我直接使用jackson对象映射器映射到json就没有这个问题,但是使用@ResponseBody注解自动序列化到json我就有这个问题了。

有人有什么想法吗?

【问题讨论】:

  • 我想我的问题可能是 configureMessageConverters 方法本身。把它拿出来,两者似乎都有效。 (现在正在处理一个休眠异常以确保它们确实如此。)

标签: java xml json spring


【解决方案1】:

我就是这样做的。

@RequestMapping(method = RequestMethod.GET, value = "/accounts/{accountId}", produces = {APPLICATION_XML_VALUE, APPLICATION_JSON_VALUE})
@ResponseBody
@ResponseStatus(value = HttpStatus.OK)
public Account getAccount(@PathVariable String accountId) {
    return new Account(); // populate Account VO and send
}

在 XML 文件中

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" >
    <mvc:message-converters register-defaults="false">
       <ref bean="xmlConverter"/>
       <ref bean="jsonConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven> 

 <!-- XML MessageConverter -->
 <bean id="xmlConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
  <constructor-arg ref="jaxbMarshaller"/>
  <property name="supportedMediaTypes" value="application/xml" />
 </bean> 

<!-- JSON MessageConverter -->
 <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
 </bean>

<!-- JAXB Classes to be marshalled -->
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="packagesToScan">
   <list>
    <value>com.test.*</value>
    <value>com.*.test</value>
  </list>
  </property>
</bean>

【讨论】:

  • 我很确定您的 MarshallingHttpMessageConverter 只是比 Jaxb2RootElementHttpMessageConverter 更手动的方式。除此之外,就我所见,你所拥有的看起来就像我所拥有的一样,除了我使用的是 Java 配置。
【解决方案2】:

我删除了configureMessageConverters,它自动拾取了两个转换器,都没有问题。

【讨论】:

    【解决方案3】:

    我也遇到了同样的情况。两次:-)

    在一种情况下,在添加我的转换器之前,一个简单的converters.clear() 解决了这个问题。看起来 Spring 默认添加了一些转换器。使用 XML 注入它们会删除 Spring 隐式设置的那个,而从代码中显式添加它们不会。

    在另一种情况下,问题是在请求中设置了正确的标头,即content-typeaccept。然后,在请求映射中,我必须指定“consumes”和“produces”参数,分别映射两个标头。

    public class MyRequestHandler {
         ...
    
         @RequestMapping(... , consumes={ MediaType.APPLICATION_JSON_VALUE, produces = { MediaType.APPLICATION_JSON_VALUE } }
         public ResponseEntity<MyResultClass> doSomething(...) { ... }
    
         ...
    }
    

    这解决了我的问题。

    【讨论】:

      【解决方案4】:

      当您覆盖 configureMessageConverters 时,它不会添加默认消息转换器。试试下面的代码。

      @Override
      public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
          converters.add(jsonConverter());
          converters.add(jaxbConverter());
          super.addDefaultHttpMessageConverters();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-16
        • 2013-07-26
        • 1970-01-01
        • 2022-09-25
        • 1970-01-01
        相关资源
        最近更新 更多