I am currently using Spring 4.1.6 with a RestTemplate to consume a third party webservice with JSON which I cannot change its behavior.I am using Jackson databind v2.6.0.
Problem: Sometimes the service returns for a member a hashmap {member:{"key":"value",...}} sometimes the same member is just an empty array {member:[]}. So I can not ignore the property by default.
Is there a way to configure the deserialization to ignore empty arrays? I saw a jackson property "WRITE_EMPTY_JSON_ARRAYS" but I am not quite sure how I can use it with my restTemplate and spring configuration.
Are there other possiblities e.g. use some combination of @JsonXXX Annotations? I saw @JsonSerialize which can be used on class level, but I don't like to write a deserializer for all my classes just to handle this situation (However if there is no other way of course I will do)
Example responses to llustrate the behavior of the service:
response with a hashmap {"id":170,"categories":{"13":"caro"}}
response with empty array of the same member {"id":170,"categories":[]}
Example of my RestTemplate usage:
BasicAuthRequestFactory requestFactory = new BasicAuthRequestFactory(httpClient);
restTemplate = new RestTemplate(requestFactory);
Article a = restTemplate.getForObject(new URI("http://..."), Article.class);
Error:
caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token
at [Source: java.io.PushbackInputStream@4aa21f9d; line: 1, column: 1456] (through reference chain: ResponseArticleWrapper["data"]->Article["categories"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
Example of my current annotated class:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(Include.NON_NULL)
public class Article {
@JsonProperty("id")
private Integer id;
@JsonProperty("categories")
private Map<Integer,String> categories = new HashMap<Integer,String>();
}
Thank you in advance for any hints and examples.
答案 0 :(得分:1)
Since jackson-databind 2.5 there is DeserializationFeature
for handling this case. It's turned off by default, so you need to configure it in your ObjectMapper
:
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
return objectMapper;
}
You can see how the custom ObjectMapper
for RestTemplate
is configured here: How can we configure the internal Jackson mapper when using RestTemplate?
After you're done with the configuration, you can just let Spring wire it for you in your class:
@Autowired
private RestOperations restTemplate;
and use the provided restTemplate
instance.