Java 如何在Spring Boot中使用显式指定的封送拆收器
我正在尝试创建一个能够生成XML输出的REST服务(我有一个自定义类,它封装在一个HATEOAS对象中)。映射如下所示: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
@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;
}
}