2014-09-27 73 views
4

我从http://www.ncpdp.org的XSD文件(仅限成员可用)中生成大量Java文件。生成它们之后,我想在我的Spring控制器中使用它们,但我在将响应转换为XML时遇到问题。从Spring引导控制器返回JAXB生成的元素

我试过返回元素本身,以及JAXBElement < T>,但似乎都没有工作。下面的测试失败:

java.lang.AssertionError: Status 
Expected :200 
Actual :406 

@Test 
public void testHelloWorld() throws Exception { 
    mockMvc.perform(get("/api/message") 
      .accept(MediaType.APPLICATION_XML) 
      .contentType(MediaType.APPLICATION_XML)) 
      .andExpect(status().isOk()) 
      .andExpect(content().contentType(MediaType.APPLICATION_XML)); 
} 

这里是我的控制器:

import org.ncpdp.schema.transport.MessageType; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

@RestController 
public class HelloWorldController { 

    @RequestMapping(value = "/api/message", method = RequestMethod.GET) 
    public MessageType messageType() { 
     return new MessageType(); 
    } 
} 

我试图创建一个MvcConfig覆盖春天启动的MVC配置,但它似乎并不奏效。

@Configuration 
@EnableWebMvc 
public class MvcConfig extends WebMvcConfigurerAdapter { 

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

    @Bean 
    public MarshallingHttpMessageConverter marshallingHttpMessageConverter() { 
     Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller(); 
     jaxb2Marshaller.setPackagesToScan(new String[]{"com.ncpdb.schema.transport"}); 

     MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(); 
     converter.setMarshaller(jaxb2Marshaller); 
     converter.setUnmarshaller(jaxb2Marshaller); 
     converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_XML)); 

     return converter; 
    } 
} 

我需要做什么才能让Spring MVC将我生成的JAXB对象编组为XML?

+0

问题:生成的'MessageType'是否有一个'@ XmlRootElement'注释。它看起来像默认的XML转换器'Jaxb2RootElementHttpMessageConverter'需要这个注释来考虑一个'MessageType'的实例来支持编组 – 2014-09-27 02:55:39

+0

@BijuKunjummen是正确的!查看https://github.com/spring-projects/spring-boot/issues/407 – geoand 2014-09-27 05:49:41

+0

GET可以真正拥有application/xml的内容类型吗?也许这是不能转换的请求? – 2014-09-27 07:21:53

回答

3

我能够通过在我的模式相同的目录下创建一个bindings.xjb文件来解决这个问题。这会导致JAXB在类上生成@XmlRootElement。

<?xml version="1.0"?> 
<jxb:bindings version="1.0" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
       xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"> 

    <jxb:bindings schemaLocation="transport.xsd" node="/xsd:schema"> 
     <jxb:globalBindings> 
      <xjc:simple/> 
     </jxb:globalBindings> 
    </jxb:bindings> 
</jxb:bindings> 

要将名称空间前缀添加到返回的XML中,我必须修改maven-jaxb2插件以添加几个参数。

<arg>-extension</arg> 
<arg>-Xnamespace-prefix</arg> 

,并添加依赖:

<dependencies> 
    <dependency> 
     <groupId>org.jvnet.jaxb2_commons</groupId> 
     <artifactId>jaxb2-namespace-prefix</artifactId> 
     <version>1.1</version> 
    </dependency> 
</dependencies> 

然后修改我的bindings.xjb包括此:

<?xml version="1.0"?> 
<jxb:bindings version="1.0" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
       xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:namespace="http://jaxb2-commons.dev.java.net/namespace-prefix" 
       xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd 
       http://jaxb2-commons.dev.java.net/namespace-prefix http://java.net/projects/jaxb2-commons/sources/svn/content/namespace-prefix/trunk/src/main/resources/prefix-namespace-schema.xsd"> 

    <jxb:bindings schemaLocation="transport.xsd" node="/xsd:schema"> 
     <jxb:globalBindings> 
      <xjc:simple/> 
     </jxb:globalBindings> 

     <jxb:schemaBindings> 
      <jxb:package name="org.ncpdp.schema.transport"/> 
     </jxb:schemaBindings> 
     <jxb:bindings> 
      <namespace:prefix name="transport"/> 
     </jxb:bindings> 
    </jxb:bindings> 
</jxb:bindings> 

我学会了如何从https://java.net/projects/jaxb2-commons/pages/Namespace-prefix做到这一点。我还发现http://blog.frankel.ch/customize-your-jaxb-bindings是关于如何定制JAXB绑定的好资源。

相关问题