从 Spring Boot Controller 返回 JAXB 生成的元素 [英] Returning JAXB-generated elements from Spring Boot Controller

查看:48
本文介绍了从 Spring Boot Controller 返回 JAXB 生成的元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆