jackson序列化Collections.unmodifiable*

har*_*aft 6 java collections serialization json jackson

我在使用json的Jackson序列化时遇到问题,如何序列化 Collections.unmodifiableMap?

我得到的错误是:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.util.Collections$UnmodifiableMap, problem: No default constructor found
Run Code Online (Sandbox Code Playgroud)

我想用SimpleAbstractTypeResolverhttp://wiki.fasterxml.com/SimpleAbstractTypeResolver但我不能得到内部类类型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), "bob@mail.com");
testAccount.setMemberEmails(emailMap);

marshalled = mapper.writeValueAsString(testAccount);
System.out.println(marshalled);
Account returnedAccount = mapper.readValue(marshalled, Account.class);
System.out.println(returnedAccount.containsValue("bob@mail.com"));


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);
  }
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?提前致谢.

Per*_*ion 3

好吧,你遇到了杰克逊的棘手案件。问题实际上是,库会很乐意使用您的 getter 方法来检索集合和映射属性,并且只有在这些 getter 方法返回 null 时才会回退到实例化这些集合/映射。

这可以通过注释组合来修复@JsonProperty/@JsonIgnore,但需要注意的是@classJSON 输出中的属性将会更改。

代码示例:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用测试代码序列化此类,您将获得以下 JSON:

{
    "@class": "misc.stack.pojo.Account",
    "memberEmails": {
        "10": "bob@mail.com",
        "@class": "java.util.HashMap"
    }
}
Run Code Online (Sandbox Code Playgroud)

这将正确反序列化。