我正在从http://www.ncpdp.org的XSD文件(仅对成员可用)生成大量Java文件。生成它们之后,我想在我的Spring Controllers中使用它们,但是在将响应转换为XML时遇到了问题。
我尝试过返回元素本身以及JAXBElement ,但似乎都不起作用。以下测试失败:
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来覆盖Spring Boot的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?
我可以通过在与架构相同的目录中创建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-plugin以添加几个参数。
<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绑定的好资源。