从 Spring Boot Controller 返回 JAXB 生成的元素 [英] Returning JAXB-generated elements from Spring Boot Controller
问题描述
我正在从 http://www.ncpdp.org 的 XSD 生成大量 Java 文件文件(仅对会员可用).生成它们后,我想在我的 Spring 控制器中使用它们,但是在将响应转换为 XML 时遇到了问题.
I'm generating a plethora of Java files from http://www.ncpdp.org's XSD files (only available to members). After generating them, I'd like to use them in my Spring Controllers, but I'm having problems getting responses converted to XML.
我尝试过返回元素本身以及 JAXBElement
I've tried returning the element itself, as well as JAXBElement<T>, but neither seems to work. The test below fails:
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 配置,但它似乎不起作用.
I've tried creating a MvcConfig to override Spring Boot's MVC config, but it doesn't seem to be working.
@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?
What do I need to do to get Spring MVC to marshall my generated JAXB objects as XML?
推荐答案
我能够通过在与我的架构相同的目录中创建一个 bindings.xjb 文件来解决这个问题.这会导致 JAXB 在类上生成 @XmlRootElement.
I was able to solve this by creating a bindings.xjb file in the same directory as my schemas. This causes JAXB to generate @XmlRootElement on classes.
<?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 以添加几个参数.
To add namespaces prefixes to the returned XML, I had to modify the maven-jaxb2-plugin to add a couple arguments.
<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 以包含以下内容:
Then modify my bindings.xjb to include this:
<?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/命名空间前缀.我还发现 http://blog.frankel.ch/customize-your-jaxb-bindings 成为有关如何自定义 JAXB 绑定的好资源.
I learned how to do this from https://java.net/projects/jaxb2-commons/pages/Namespace-prefix. I also found http://blog.frankel.ch/customize-your-jaxb-bindings to be a good resource on how to customize JAXB bindings.
这篇关于从 Spring Boot Controller 返回 JAXB 生成的元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!