首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >杰克逊序列化Collections.unmodifiable*

杰克逊序列化Collections.unmodifiable*
EN

Stack Overflow用户
提问于 2013-07-12 17:59:10
回答 2查看 5.4K关注 0票数 8

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

我得到的错误是:

代码语言:javascript
复制
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.util.Collections$UnmodifiableMap, problem: No default constructor found

我想使用来自http://wiki.fasterxml.com/SimpleAbstractTypeResolverSimpleAbstractTypeResolver,但是我无法获得内部类类型Collections$UnmodifiableMap

代码语言:javascript
复制
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);
  }

有什么想法吗?提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-12 23:15:55

好的,你遇到了一个关于杰克逊的悬而未决的案子。真正的问题是,该库将很乐意使用您的getter方法来检索集合和映射属性,并且只有在这些getter方法返回null时才会回退到实例化这些集合/映射。

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

代码示例:

代码语言:javascript
复制
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);
    }
}

如果你用你的测试代码序列化这个类,你会得到下面的JSON:

代码语言:javascript
复制
{
    "@class": "misc.stack.pojo.Account",
    "memberEmails": {
        "10": "bob@mail.com",
        "@class": "java.util.HashMap"
    }
}

它将正确地反序列化。

票数 3
EN

Stack Overflow用户

发布于 2013-07-12 18:28:01

Jackson首先寻找的是默认构造函数。如果要使用不同的构造函数,则需要在其上指定add @JsonCreator并在其参数上指定@JsonProperty注解。

由于您无法将这些注释添加到Collections.UnmodifiableCollection中,因此无法对其进行反序列化。

  1. 你可能不需要使用不可修改的集合来序列化。这有什么意义?您可以在反序列化对象时执行此操作。而且,反序列化的对象将不同于序列化的(复制的)
  2. ,如果你真的需要它,你可以简单地编写你自己的UnmodifiableCollection类。它非常简单,因为它只是集合的包装器,并将方法调用委托给底层集合

公共布尔型isEmpty() { c.isEmpty();} // c是底层集合

除修改方法外:

public boolean add(E e) {抛出新的UnsupportedOperationException();}.....

  • 您也可以在序列化之前调用其中一个方法来序列化数组。反序列化时,通过从数组创建集合来构建模型对象,并通过返回不可修改的集合的getter来访问此集合:

public Object[] toArray();public T[] toArray(T[] a);

  • 您可以将@JsonIgnore添加到模型中的getter方法中,并将@JsonValue添加到memberEmails字段中。

  • 您可以创建另一个getter (私有的,具有不同名称),并将其注释为字段的@JsonValue

<代码>G219

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17612301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档