使用 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;
}
使用 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;
}