使用 RestTemplate 编组 Spring 数据 REST 查询结果

Marshalling Spring Data REST Query Results with RestTemplate

使用 RestTemplate.exchange 调用查询端点时,我应该期待什么 return 类型?

我的存储库有一个方法:

Page<Account> findAccountByFirstName(String name, Pageable pageable);

在我的集成测试中,我使用 RestTemplate:

进行以下调用
ResponseEntity<List<Account>> accountResponse = restPleb.exchange(
    new RequestEntity<Void>(HttpMethod.GET, getUri("/accounts/search/findByFirstName?firstName=Kevin")), 
    new ParameterizedTypeReference<List<Account>>() {}
);

响应包含在名为 accounts:

的对象中找到的资源列表
{
  "_embedded" : {
    "accounts" : [ {
      "lastName" : "Lastname",
      "firstName" : "Kevin",
      "phoneNumber " : "+44 7700000000",
      "email" : "kevin@example.com",
      "_links" : {
        "self" : {
          "href" : "http://localhost:53826/accounts/id"
        },
        "persistableAccount" : {
          "href" : "http://localhost:53826/accounts/id"
        }
      }
    } ]
  },
  "_links" : {
    "self" : {
      "href" : "http://localhost:53826/accounts/search/findByFirstName?firstName=Kevin"
    }
  },
  "page" : {
    "size" : 20,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}

我收到以下错误,其中 RestTemplate 和 Jackson 无法弄清楚如何处理响应。大概这是因为它需要一个数组而不是一个对象。

org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token

有什么方法可以让 RestTemplate 向 Jackson 提供正确的反序列化提示吗?我本以为一定有办法,因为它是 Spring 在鸿沟的两边!

更新

我试过将响应类型指定为 Resources<Account>,这样可以防止抛出异常,而是给出一个空列表:Resources { content: [], links: [] }

根据 format, it has to be parsed in a different manner is what I suppose. Can this example be used to parse - defined here

将转换器注册到模板 -> 并使用资源解析响应。

public RestTemplate getRestTemplateWithHalMessageConverter() {
 RestTemplate restTemplate = new RestTemplate();
 List<HttpMessageConverter<?>> existingConverters = restTemplate.getMessageConverters();
 List<HttpMessageConverter<?>> newConverters = new ArrayList<>();
 newConverters.add(getHalMessageConverter());
 newConverters.addAll(existingConverters);
 restTemplate.setMessageConverters(newConverters);
 return restTemplate;
}
 
private HttpMessageConverter getHalMessageConverter() {
 ObjectMapper objectMapper = new ObjectMapper();
 objectMapper.registerModule(new Jackson2HalModule());
 MappingJackson2HttpMessageConverter halConverter = new TypeConstrainedMappingJackson2HttpMessageConverter(ResourceSupport.class);
 halConverter.setSupportedMediaTypes(Arrays.asList(HAL_JSON));
 halConverter.setObjectMapper(objectMapper);
 return halConverter;
}