Spring Data REST - 使用实体列表,Java HATEOAS客户端

时间:2016-07-19 21:28:33

标签: rest spring-mvc spring-data-rest spring-hateoas

我正在使用Spring Data REST 2.5.1,Jackson 2.8.0,Spring Boot 1.3.6。

我正在尝试通过RestTemplate从我的存储库中检索一个简单的实体列表。我可以在浏览器中找到终点,并获得预期的HAL数据。检索单个实体可以正常工作,如下所示。这些都使用默认的SDR端点(例如localhost:{port} / myEntity)。

    ResponseEntity<Resource<MyEntity>> responseEntity =
    new RestTemplate()
        .exchange(
        uri + "/1",
            HttpMethod.GET,
            HttpEntity.EMPTY,
        new ParameterizedTypeReference<Resource<MyEntity>>() {}, port
        )

或者     new RestTemplate()。getForEntity(uri +“/ 1”,MyEntity.class,port)

正如许多SO问题似乎表明的那样,找到检索列表的示例是一个问题。我已经使用ParameterizedTypeReferenceResourcesResource,数组,List尝试了MyEntity。一切都没有运气。

        ResponseEntity<Resources<Resource<MyEntity>>> responseEntity =
            new RestTemplate()
                    .exchange(
                    uri,
                    HttpMethod.GET,
                    HttpEntity.EMPTY,
                    new ParameterizedTypeReference<Resources<Resource<MyEntity>>>() {}
            , port
            )

如上所述调用几乎任何种类的ResourcesResourceList<MyEntity>MyEntity等,ResponseEntity为空。像:

<200 OK,Resources { content: [], links: [] },{Server=[Apache-Coyote/1.1], Content-Type=[application/json;charset=UTF-8], Transfer-Encoding=[chunked], Date=[...]}>

字符串JSON在浏览器中如下所示。

{
"_embedded" : {
"myEntities" : [ ... ]
},
"_links" : {
"self" : {
  "href" : "http://localhost:8080/myEntity"
},
"profile" : {
  "href" : "http://localhost:8080/profile/myEntity"
},
"search" : {
  "href" : "http://localhost:8080/myEntity/search"
}
},
"page" : {
  "size" : 20,
  "totalElements" : 10,
  "totalPages" : 1,
  "number" : 1
 }
}

存储库定义:

@RepositoryRestResource(collectionResourceRel = "myEntities", path = "myEntity")
public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, Long>
, QueryDslPredicateExecutor<MyEntity>
, QuerydslBinderCustomizer<QMyEntity> { }

对我遗失的内容有任何疑问?

2 个答案:

答案 0 :(得分:8)

我通过做一些事情来解决这个问题。

  1. 我不得不更新到spring-hateoas:0.20.0.RELEASE从0.19.0开始。 spring-hateoas:0.19.0不支持指定here的jackson 2.7+。

  2. 我更新了我的客户电话,如下所示。

    ObjectMapper mapper = builder.build()
    MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
    
    messageConverter.setSupportedMediaTypes(MediaType.parseMediaTypes("application/hal+json"))
    messageConverter.setObjectMapper(mapper)
    
    ResponseEntity<PagedResources<MyEntity>> responseEntity =
            new RestTemplate(Arrays.asList(messageConverter))
                    .exchange(
                    uri,
                    HttpMethod.GET,
                    HttpEntity.EMPTY,
                    new ParameterizedTypeReference<PagedResources<MyEntity>>() {}, port
            )
    
  3. PagedResources现在看起来像这样:

    <200 OK,PagedResource { content: [{<List of MyEntities>}], metadata: Metadata { number: 0, total pages: 1, total elements: 10, size: 20 }, links: [<List of hateoas links for MyEntities>] },{Server=[Apache-Coyote/1.1], Content-Type=[application/hal+json;charset=UTF-8], Transfer-Encoding=[chunked], Date=[Thu, 21 Jul 2016 14:57:18 GMT]}>
    

    @ zeroflagL的评论让我更仔细地研究了PagedResources的实施,最终导致了'啊哈!'这个blog的时刻。

    相关位是默认RestTemplate未将接受标头设置为application/hal+json。相反,默认值为application/x-spring-data-compact+json;charset=UTF-8,其中没有内容且仅包含链接。这就是我为Resources类型获取空内容的原因。如上所述明确设置MediaType可以解决问题。

答案 1 :(得分:1)

这是我的解决方法:

    ParameterizedTypeReference<PagedResources<EntityObject>> responseType;
    responseType = new ParameterizedTypeReference<PagedResources<EntityObject>>() { };

    ResponseEntity<PagedResources<EntityObject>> pageResources;
    pageResources = restTemplate
            .withBasicAuth(username, password)
            .exchange(
                    UriComponentsBuilder.fromPath("/your/api/path").build().toString(),
                    GET,
                    null,
                    responseType
            );

    PagedResources<EntityObject> resource = pageResources.getBody();
    assertTrue(resource.getContent().isEmpty());