spring - 春季测试休息模板:无法提取响应:没有找到适合响应类型的 HttpMessageConverter
问题描述
我得到这个例外
org.springframework.web.client.RestClientException:无法提取响应:没有找到适合响应类型 [AnalyticsResponse] 和内容类型 [application/json;charset=UTF-8] 的 HttpMessageConverter
如果我的 DTO 包含一个以用户定义的类作为键的映射,则仅在我的 junit 测试用例中(其余端点工作正常)
@Data
public class AnalyticsResponse {
private List<Committer> commitersList; //OK
private Map<Committer , Long> comittersCommitsMap; // Problem
private Map<Date, List<CommitItem>> commitItemsTimeLineMap; //OK
}
如果 committersCommitsMap 字段被删除,一切都会好起来的
我的测试用例代码片段:
ResponseEntity<AnalyticsResponse> analyticsResponse = testRestTemplate.getForEntity(ANALYSIS_CONTROLLER_BASE_URL+"analytics?repo-full-name=" + searchResponse.getBody().get(0).getFull_name() ,
AnalyticsResponse.class);
---更新:提交者类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Committer {
private String name;
private String email;
}
解决方案
默认情况下,ObjectMapper无法确定Map
akey
不是 a 的序列化和反序列化String
,您必须提供自定义实现。
为and实现KeyDeserializer和JsonSerializer(作为Map的键)Committer
Date
配置ObjectMapper
-使用KeyDeserializer和KeySerializer ( JsonSerializer )注册模块
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
// KeyDeserializer for Committer (simple without 'null' check)
@RequiredArgsConstructor
public static class CommitterKeyDeserializer extends KeyDeserializer {
private final ObjectMapper mapper;
@Override
public Object deserializeKey(final String key,
final DeserializationContext ctxt)
throws IOException, JsonProcessingException {
return mapper.readValue(key, Committer.class);
}
}
// KeyDeserializer for Date (simple without 'null' check)
@RequiredArgsConstructor
public static class DateKeyDeserializer extends KeyDeserializer {
private final ObjectMapper mapper;
@Override
public Object deserializeKey(final String key,
final DeserializationContext ctxt)
throws IOException, JsonProcessingException {
return mapper.readValue(key, Date.class);
}
}
// JsonSerializer for Committer (simple without 'null' check)
@RequiredArgsConstructor
public static class CommitterJsonSerializer extends JsonSerializer<Committer> {
private final ObjectMapper mapper;
@Override
public void serialize(Committer committer,
JsonGenerator jgen,
SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeFieldName(mapper.writeValueAsString(committer));
}
}
// JsonSerializer for Date (simple without 'null' check)
public static class DateJsonSerializer extends JsonSerializer<Date> {
@Override
public void serialize(Date date,
JsonGenerator jgen,
SerializerProvider provider)
throws IOException, JsonProcessingException {
jgen.writeFieldName(String.valueOf(date.getTime()));
}
}
// ObjectMapper configuration
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// register module with custom serializers and deserializers
mapper.registerModule(new SimpleModule()
.addKeyDeserializer(
Committer.class,
new CommitterKeyDeserializer(mapper))
.addKeyDeserializer(
Date.class,
new DateKeyDeserializer(mapper))
.addKeySerializer(
Committer.class,
new CommitterJsonSerializer(mapper))
.addKeySerializer(
Date.class,
new DateJsonSerializer()));
return mapper;
}
// RestTemplate configuration
@Bean
public RestTemplate restTemplate(List<HttpMessageConverter<?>> converters) {
RestTemplate restTemplate = new RestTemplate();
// add spring's predefined converters
restTemplate.setMessageConverters(converters);
return restTemplate;
}
}
请注意,在这个简单的实现中,键 Committer
在JSON 响应中comittersCommitsMap
表示为字符串RestTemplate
(此实现也可以):
{
"commitersList": [
{
"name": "name",
"email": "email"
}
],
"comittersCommitsMap": {
"{\"name\":\"name\",\"email\":\"email\"}": 1
},
"commitItemsTimeLineMap": {
"1570929503854": [
{
"data": "data"
}
]
}
}
推荐阅读
- java - 共享相同模型的重复 TableView
- php - 使用php在csv文件中连续添加2列
- scala - scala中“map”的通用容器类型(更高类型)
- python - 使用具有多个预处理功能的 keras ImageDataGenerator
- javascript - 为什么要在 redux store 中放置同步状态?
- mysql - 数据库触发器 - 当更新行中的字段等于三个值之一时,更新另一个表
- php - 使用正则表达式捕获评论
- php - php copy() 复制多个文件时关闭连接
- javascript - 从 S3 getObject() 中检索图像不起作用
- amazon-web-services - 为 AWS ELB 生成公有/后端密钥