如何确保application / hal + json是第一个受支持的媒体类型

时间:2019-05-29 03:06:00

标签: spring-hateoas

我使用spring-boot-starter-data-rest创建了启用了Hateoas的Rest服务,效果很好。
然后,我在另一个spring boot模块中创建了该rest服务的客户端:这是一个依赖关系,可以包含在其他要使用rest服务的项目中。它在后台使用了restTemplate。 为了使其正常工作,它与HttpMessageConverters和TypeConstrainedMappingJackson2HttpMessageConverter进行了一些混搭。

我尝试在主应用程序中使用此依赖项,但它未能填充ResponseEntity >中的链接,导致空指针异常。

我无法找到问题所在,所以我创建了一个基本的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应用程序类型:无”操作,如何使HypermediaHttpMessageConverterConfiguration运行?

1 个答案:

答案 0 :(得分:0)

我发现将其添加到配置类中可以达到目的:     @Import(RepositoryRestMvcConfiguration.class)

RepositoryRestMvcConfiguration似乎通过在HttpMessageConverters列表中位置0处添加RepositoryRestMvcConfiguration.ResourceSupportHttpMessageConverter来使hal + json具有最高优先级。