繁体   English   中英

如何在 Spring 引导中使用明确指定的编组器

[英]How to use an explicitly specified marshaller in Spring Boot

I'm trying to create a REST service that is able to produce XML output (I have a custom class that is wrapped inside a HATEOAS object). 映射是这样的:

@GetMapping("/customclass")
Resource<CustomClass> custom() {
    return new Resource<CustomClass>(new CustomClass());
}

Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not marshal [Resource { content: CustomClass(a=10, string=abc), links: [] }]: null; nested exception is javax.xml.bind.MarshalException
 - with linked exception:
[com.sun.istack.internal.SAXException2: class test.CustomClass nor any of its super class is known to this context.
javax.xml.bind.JAXBException: class test.CustomClass nor any of its super class is known to this context.]]

我很确定我的 CustomClass 没有任何问题。 如果我改用以下映射

@GetMapping("/customclass")
CustomClass custom() {
    return (new CustomClass());
}

然后它工作正常。

如果我尝试手动编组(通过在 main 方法中设置内容然后运行它),它也可以正常工作。 如果我将 CustomClass 的实例包装在 Resource 实例中也很好。

据我了解,问题在于 SpringApplication 中的编组器正在使用只知道 HATEOAS 资源的上下文,我需要一些如何让它知道 CustomClass。

我尝试使用这样的东西(来自https://stackoverflow.com/a/40398632

@Configuration
public class ResponseResolver  {
    @Bean
    public Marshaller marshaller() {
        try {
            System.out.println("getting marshaller");
            JAXBContext context = JAXBContext.newInstance(CustomClass.class, Resource.class);
            return context.createMarshaller();
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }
    }
}

但这没有用(我在这里有很多猜测,因为我不太了解 Spring Boot 的内部工作原理)。

https://stackoverflow.com/a/14073899中也有一个有希望的答复,但 ContextResolver 不在我的项目类路径中。

我还考虑将 Resource 包装在另一个 class 中,然后使用 XmlSeeAlso 注释,但这会弄乱我的 XML 并且会有点难看。

那么是否可以定义一个 SpringApplication 能够获取的自定义 JAXBContext 呢?

来自 Spring 引导文档Spring 消息消息转换器

Spring MVC 使用 HttpMessageConverter 接口来转换 HTTP 请求和响应。 明智的默认设置是开箱即用的。 For example, objects can be automatically converted to JSON (by using the Jackson library) or XML (by using the Jackson XML extension, if available, or by using JAXB if the Jackson XML extension is not available). 默认情况下,Jaxb2RootElementHttpMessageConverter – 将 Java 对象转换为 XML (仅当 JAXB2 存在于类路径中时才添加)

自定义转换器配置

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(
      List<HttpMessageConverter<?>> converters) {

        messageConverters.add(createXmlHttpMessageConverter());
        messageConverters.add(new MappingJackson2HttpMessageConverter());
    }
    private HttpMessageConverter<Object> createXmlHttpMessageConverter() {
        MarshallingHttpMessageConverter xmlConverter = 
          new MarshallingHttpMessageConverter();

        XStreamMarshaller xstreamMarshaller = new XStreamMarshaller();
        xmlConverter.setMarshaller(xstreamMarshaller);
        xmlConverter.setUnmarshaller(xstreamMarshaller);

        return xmlConverter;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM