spring-hateoas - 如何确保 application/hal+json 是第一个支持的媒体类型
问题描述
我使用 spring-boot-starter-data-rest 创建了一个启用 Hateoas 的 Rest 服务,效果很好。
然后,我在另一个 Spring Boot 模块中创建了该休息服务的客户端:这是一个可以包含在其他想要使用休息服务的项目中的依赖项。它在引擎盖下使用了一个 restTemplate。HttpMessageConverters 和 TypeConstrainedMappingJackson2HttpMessageConverter 花了一些时间才能让它工作,但确实如此。
我尝试在我的主应用程序中使用此依赖项,但它无法填充 ResponseEntity< Resource< Myclass>> 中的链接,从而导致空指针异常。
我找不到问题,所以我创建了一个基本的 Spring Boot 应用程序 2.1.5.RELEASE 并让客户端正常工作,然后将问题追溯到我的主应用程序中的这个配置,不幸的是,这需要另一个问题:
spring:
main:
web-application-type: none
如果存在此配置,似乎 hal+json 不是第一个接受的媒体类型
org.springframework.core.log.CompositeLog.debug(CompositeLog.java:147) : Accept=[application/json, application/hal+json, application/octet-stream, application/*+json]
删除配置后,我看到
org.springframework.core.log.CompositeLog.debug(CompositeLog.java:147) : Accept=[application/hal+json, application/json, application/octet-stream, application/*+json]
我可以看到这个记录,它解决了我假设的问题(发生错误时没有记录)
- @ConditionalOnProperty (spring.hateoas.use-hal-as-default-json-media-type) matched (OnPropertyCondition)
我已尝试添加此配置以强制解决此问题,但它不起作用
spring:
hateoas:
use-hal-as-default-json-media-type: true
这是我在其余客户端中配置消息转换器的代码:
@Configuration
public class MessageConverterConfiguration {
@Bean public TypeConstrainedMappingJackson2HttpMessageConverter myhalJacksonHttpMessageConverter(){
return new TypeConstrainedMappingJackson2HttpMessageConverter( ResourceSupport.class );
}
/**
* Add {@link TypeConstrainedMappingJackson2HttpMessageConverter} to the list of {@link HttpMessageConverter}s
* configured in the {@link RestTemplate} in first position ( this position is critical ).
* @param halJacksonHttpMessageConverter automagically configured by spring-boot-starter-hateoas
* @return List of {@link HttpMessageConverter}s
*/
@Bean( name = "hal-jackson" ) public List< HttpMessageConverter<?> > mymessageConverters( TypeConstrainedMappingJackson2HttpMessageConverter halJacksonHttpMessageConverter ) {
final List<HttpMessageConverter<?>> all = new ArrayList<>( );
all.add( halJacksonHttpMessageConverter );
all.add( jacksonConverterWithOctetStreamSupport( ) );
all.addAll( new RestTemplate().getMessageConverters() );
return all;
}
/**
* This allows converting octet stream responses into {@link LastApplicationRun} ,
* when we create a last run by posting with {@link RestTemplate#postForObject(URI , Object, Class)}
* : without it we get a
* <pre>org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter
* found for response type [class com.sparknz.ced.spark.sampling.rest.tobesampled.client.domain.LastApplicationRun]
* and content type [application/octet-stream]</pre>.
* <p></p>
* I could find no better solution: it is not needed when we make a get call, don't understand why we get an octet stream response.
* It may only now be useful for tests.
*/
private MappingJackson2HttpMessageConverter jacksonConverterWithOctetStreamSupport( ) {
final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(
asList(new MediaType[]{
MediaType.valueOf( "application/hal+json" ) ,
MediaType.APPLICATION_JSON,
MediaType.APPLICATION_OCTET_STREAM }));
return converter;
}
}
'web-application-type: none' 是做什么的,如何让 HypermediaHttpMessageConverterConfiguration 运行?
解决方案
我发现将它添加到我的配置类中就可以了:@Import(RepositoryRestMvcConfiguration.class)
RepositoryRestMvcConfiguration 似乎负责通过在 HttpMessageConverters 列表中的位置 0 处添加 RepositoryRestMvcConfiguration.ResourceSupportHttpMessageConverter 来使 hal+json 成为最高优先级。
推荐阅读
- innerhtml - 有没有办法搜索搜索所有字符(包括“<”字符)的字符串?
- python - 如何合并修改数据框中数据的列
- vulkan - Ubuntu 20 上的 Vulkan 验证层
- jhipster - 删除 JDL 上的 DTO 和服务后不清理代码
- perforce - Perforce - p4 同步命令不起作用
- gatsby - 来自阵列的动态图像
- firebase - 更改页面 Flutter 时丢失 GoogleSignInAccount
- amazon-web-services - 将消息从一个帐户中的 lambda 发送到另一个帐户中的 SQS
- python - 如何在自定义类中重载双重比较?(x < 我的对象 < y)
- javascript - 未知命令:运行 npm 命令时的“pkg”