Java 如何在Spring Boot中使用显式指定的封送拆收器

Java 如何在Spring Boot中使用显式指定的封送拆收器,java,spring,rest,spring-boot,jaxb,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.HttpMessage

我正在尝试创建一个能够生成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的实例包装在资源实例中也可以

据我所知,问题在于SpringApplication中的封送处理程序使用的是只知道HATEOAS资源的上下文,我需要了解如何让它知道CustomClass

我试着用这样的东西(来自)

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

还有一个很有希望的答复,但ContextResolver不在我的项目类路径中

我还考虑过将资源包装到另一个类中,然后使用XMLSeeAllow注释,但这会弄乱我的XML,并且会有点难看


那么,是否可以定义SpringApplication能够从Spring引导文档中获取的自定义JAXBContext?

SpringMVC使用HttpMessageConverter接口转换HTTP 请求和答复。合理的默认设置包括开箱即用。 例如,对象可以自动转换为JSON(通过使用 Jackson库)或XML(如果需要,可以使用Jackson XML扩展名) 如果Jackson XML扩展不可用,则可以使用JAXB 可用)。默认情况下,Jaxb2RootElementHttpMessageConverter—— 将Java对象转换为XML或从XML转换为Java对象(仅当上存在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;
    }
}
@配置
公共类WebConfig实现WebMVCConfiguer{
@凌驾
公共无效配置MessageConverters(

ListThis为我指明了正确的方向,我成功地让它工作。您提供的代码有几个问题。出于某种原因,
new MappingJackson2HttpMessageConverter()
Accept:application/xml
请求没有任何影响。但是,当将
createXmlHttpMessageConverter
设置为public
并向其添加
@Bean
注释时,您的解决方案会起作用(然后Spring boot会自动拾取它)。谢谢!你知道为什么添加转换器是用这两个添加项来实现的吗?
@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);
        }
    }
}
@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;
    }
}