默认情况下,ObjectMapper
我收到此异常
),如果我的DTO包含以用户定义的类作为键的映射org.springframework.web.client.RestClientException:无法提取响应:找不到适合于响应类型[AnalyticsResponse]和内容类型[application / json; charset = UTF-8]]的HttpMessageConverter>
仅在我的junit测试用例中(Rest端点工作正常
@Data public class AnalyticsResponse { private List<Committer> commitersList; //OK private Map<Committer , Long> comittersCommitsMap; // Problem private Map<Date, List<CommitItem>> commitItemsTimeLineMap; //OK }
如果删除了comittersCommitsMap字段,则一切正常
我的测试用例代码段:
ResponseEntity<AnalyticsResponse> analyticsResponse = testRestTemplate.getForEntity(ANALYSIS_CONTROLLER_BASE_URL+"analytics?repo-full-name=" + searchResponse.getBody().get(0).getFull_name() , AnalyticsResponse.class);
---更新:Committer类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Committer {
private String name;
private String email;
}
我收到此异常org.springframework.web.client.RestClientException:无法提取响应:找不到适用于响应类型[AnalyticsResponse]和内容类型[...]的HttpMessageConverter,>
默认情况下,ObjectMapper
Map
不是key
的String
的序列化和反序列化,您必须提供自定义实现。为KeyDeserializer和JsonSerializer实现Committer
和Date
(作为Map
使用ObjectMapper
和register(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
中的[[keycomittersCommitsMap
在JSON响应中表示为StringRestTemplate
也起作用:]]]]{ "commitersList": [ { "name": "name", "email": "email" } ], "comittersCommitsMap": { "{\"name\":\"name\",\"email\":\"email\"}": 1 }, "commitItemsTimeLineMap": { "1570929503854": [ { "data": "data" } ] } }
默认情况下,ObjectMapper