I have a problem using the Jackson serialization from json, how do I serialize from Collections.unmodifiableMap?
The error I get is:
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.util.Collections$UnmodifiableMap, problem: No default constructor found
I wanted to use the SimpleAbstractTypeResolver
from http://wiki.fasterxml.com/SimpleAbstractTypeResolver however I cannot get the inner class type Collections$UnmodifiableMap
Map<Integer, String> emailMap = newHashMap();
Account testAccount = new Account();
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, As.PROPERTY);
String marshalled ;
emailMap.put(Integer.valueOf(10), "[email protected]");
testAccount.setMemberEmails(emailMap);
marshalled = mapper.writeValueAsString(testAccount);
System.out.println(marshalled);
Account returnedAccount = mapper.readValue(marshalled, Account.class);
System.out.println(returnedAccount.containsValue("[email protected]"));
public class Account {
private Map<Integer, String> memberEmails = Maps.newHashMap();
public void setMemberEmails(Map<Integer, String> memberEmails) {
this.memberEmails = memberEmails;
}
public Map<Integer, String> getMemberEmails() {
return Collections.unmodifiableMap(memberEmails);
}
Any ideas? Thanks in advance.
Collections that do not support modification operations (such as add , remove and clear ) are referred to as unmodifiable. Collections that are not unmodifiable are modifiable. Collections that additionally guarantee that no change in the Collection object will be visible are referred to as immutable.
List<E>. unmodifiable constructor Null safety The Iterator of elements provides the order of the elements. An unmodifiable list cannot have its length or elements changed. If the elements are themselves immutable, then the resulting list is also immutable.
Jackson uses default (no argument) constructor to create object and then sets value using setters. so you only need @NoArgsConstructor and @Setter. Save this answer.
Okay, you've run into an edge-ish type case with Jackson. The problem really is that the library will happily use your getter method to retrieve collection and map properties, and only falls back to instantiating these collections/maps if those getter methods return null.
This can fixed by a combination of @JsonProperty/@JsonIgnore
annotations, with the caveat that the @class
property in your JSON output will change.
Code example:
public class Account {
@JsonProperty("memberEmails")
private Map<Integer, String> memberEmails = Maps.newHashMap();
public Account() {
super();
}
public void setMemberEmails(Map<Integer, String> memberEmails) {
this.memberEmails = memberEmails;
}
@JsonIgnore
public Map<Integer, String> getMemberEmails() {
return Collections.unmodifiableMap(memberEmails);
}
}
If you serialize this class with your test code you will get the following JSON:
{
"@class": "misc.stack.pojo.Account",
"memberEmails": {
"10": "[email protected]",
"@class": "java.util.HashMap"
}
}
Which will deserialize correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With