Spring HATEOAS (w Spring Boot) JAXB 封送错误,返回资源<T>或分页资源<T>结果



在我的控制器中有这样的内容:

@RequestMapping
@ResponseBody
public HttpEntity<PagedResources<PromotionResource>> promotions(
        @PageableDefault(size = RestAPIConfig.DEFAULT_PAGE_SIZE, page = 0) Pageable pageable,
        PagedResourcesAssembler<Promotion> assembler
){
    PagedResources<PromotionResource> r = assembler.toResource(this.promoService.find(pageable), this.promoAssembler);
    return new ResponseEntity<PagedResources<PromotionResource>>(r, HttpStatus.OK);
}

如果我导航到映射到该控制器方法的URL,我会得到一个500错误,其根本原因是:

com.sun.istack.internal.SAXException2: unable to marshal type "commerce.api.rest.resources.PromotionResource " as an element because it is missing an @XmlRootElement annotation 

如果我在我的资源上抛出一个@XmlRootElement注释,它会变成这个错误:

com.sun.istack.internal.SAXException2: unable to marshal type "commerce.api.rest.resources.PromotionResource " as an element because it is not known to this context.

如果接收头是application/json或application/hal+json,一切都很好。只有当客户端(在这种情况下chrome)正在寻找应用程序/xml(这是有意义的,因为HATEOAS是遵循客户端的请求。我正在使用spring boot的@EnableAutoConfiguration,它将XML消息转换器添加到列表中,从而启用XML内容类型。

我猜我至少有2个选择:1. 修复jaxb错误2. 删除XML作为支持的内容类型

不知道怎么做,或者有其他的选择。

如果您实际上不想生成XML,请尝试使用@RequestMapping注释的produces属性。例如:@RequestMapping(produces=MediaType.APPLICATION_JSON_VALUE)

或者你可以从你的类路径中排除jaxb,或者看看添加你自己的org.springframework.boot.autoconfigure.web.HttpMessageConverters bean来完全控制注册的HttpMessageConverter。参见WebMvcConfigurationSupport.addDefaultHttpMessageConverters,看看Spring默认会添加什么

不确定这是一个好技术,看起来在1.1.6中有一个不同的方法。我是这样做的:

@Configuration
public class WebMVCConfig extends WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //Remove the Jaxb2 that is automatically added because some other dependency brings it into the classpath
        List<HttpMessageConverter<?>> baseConverters = new ArrayList<HttpMessageConverter<?>>();
        super.configureMessageConverters(baseConverters);
        for(HttpMessageConverter<?> c : baseConverters){
            if(!(c instanceof Jaxb2RootElementHttpMessageConverter)){
                converters.add(c);
            }
        }
    }
}

如果你不想支持XML转换器,你可以扩展spring WebMvcConfigurer来排除XML消息转换器。

@Configuration
public class WebMVCConfig extends WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter {
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.removeIf(c -> c instanceof AbstractXmlHttpMessageConverter<?>);
    }
}

相关内容

最新更新