java - 如何在 Spring Boot 中使用显式指定的编码器

标签 java spring rest spring-boot jaxb

我正在尝试创建一个能够生成 XML 输出的 REST 服务(我有一个封装在 HATEOAS 对象内的自定义类)。映射是这样的:

@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());
}

然后就可以正常工作了。

如果我尝试手动编码(marshal)事物(通过在主方法内设置事物然后运行它),它也可以正常工作。如果我将 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 包装在另一个类中,然后使用 XmlSeeAlso 注释,但这会弄乱我的 XML,并且会有点难看。

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

最佳答案

来自 Spring Boot 文档 Spring Message message converters

Spring MVC uses the HttpMessageConverter interface to convert HTTP requests and responses. Sensible defaults are included out of the box. 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). By default, Jaxb2RootElementHttpMessageConverter – converts Java objects to/from XML (added only if JAXB2 is present on the classpath)

自定义转换器配置

@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;
    }
}

关于java - 如何在 Spring Boot 中使用显式指定的编码器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58038696/

相关文章:

java - 如何解决 klov -Extent 报告中的 FileSizeLimitExceededException

spring - 如何最好地处理 Spring JDBC 中的约束冲突

java - 将 reSTLet 与 Eclipse Virgo 结合使用

python - 测试经过身份验证的 django-rest-framework 路由时出现 405 错误

web-services - 用于测试RESTful Web服务的工具

java - 获取分配给 Kafka 分区的消费者或客户端 ID

java - 不包含在正则表达式中

java - 如何按值设置选定的索引JComboBox

java - 如何将对象添加到枚举定义的类中?

api - curl -- 使用 PAW-App 进行摘要式身份验证