Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java jackson正在序列化集合。不可修改*_Java_Json_Serialization_Collections_Jackson - Fatal编程技术网

Java jackson正在序列化集合。不可修改*

Java jackson正在序列化集合。不可修改*,java,json,serialization,collections,jackson,Java,Json,Serialization,Collections,Jackson,我在使用json的Jackson序列化时遇到问题,如何从集合进行序列化。不可修改映射? 我得到的错误是: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.util.Collections$UnmodifiableMap, problem: No default constructor found 我想从中使用SimpleAstractTypeResolver,但是我无

我在使用json的Jackson序列化时遇到问题,如何从
集合进行序列化。不可修改映射?

我得到的错误是:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.util.Collections$UnmodifiableMap, problem: No default constructor found
我想从中使用
SimpleAstractTypeResolver
,但是我无法获取内部类类型
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);
  }
Map emailMap=newHashMap();
账户testAccount=新账户();
ObjectMapper mapper=新的ObjectMapper();
enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL,As.PROPERTY);
串编组;
emailMap.put(整型.valueOf(10),”bob@mail.com");
testAccount.setMemberEmails(emailMap);
marshalled=mapper.writeValueAsString(testAccount);
系统输出打印项次(编组);
Account returnedAccount=mapper.readValue(已封送,Account.class);
System.out.println(返回的帐户包含值(“bob@mail.com"));
公共类帐户{
private Map memberEmails=Maps.newHashMap();
公共无效setMemberEmails(映射成员电子邮件){
this.memberEmails=memberEmails;
}
公共地图getMemberEmails(){
返回集合。不可修改映射(MemberEmail);
}

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

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

由于您无法将这些批注添加到
集合中。无法修改的集合将无法对其进行反序列化

  • 您可能不需要使用不可修改的集合进行序列化。这有什么意义?您可以在反序列化对象时这样做。反序列化的对象也将不同于序列化的对象(副本)

  • 如果您真的需要,您只需编写自己的
    UnmodifiableCollection
    类即可。它非常简单,因为它只是集合的包装器,并将方法调用委托给基础集合

    public boolean isEmpty() { return c.isEmpty(); } // c is underlying collection
    
    除修改方法外:

    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }
    .....
    
  • 您还可以在序列化之前调用其中一个方法来序列化数组。在反序列化生成对象时,您可以使用从数组创建集合来建模对象,并使用getter返回不可修改集合来访问此集合:

    public Object[] toArray();
    public <T> T[] toArray(T[] a);
    
    公共对象[]toArray();
    公共T[]阵列(T[]a);
    
  • 您可以将
    @JsonIgnore
    添加到模型中的getter方法中,并将
    @JsonValue
    添加到
    成员电子邮件
    字段中

  • 您可以为字段创建另一个getter(private和其他名称),并将其注释为
    @JsonValue


  • 好的,您在Jackson中遇到了一个edge-ish类型的情况。问题是库会很高兴地使用您的getter方法来检索集合和映射属性,并且只有在这些getter方法返回null时才会返回到实例化这些集合/映射

    这可以通过组合使用
    @JsonProperty/@JsonIgnore
    注释来解决,但需要注意的是,JSON输出中的
    @class
    属性将发生更改

    代码示例:

    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);
        }
    }
    

    这将正确反序列化。

    谢谢Tala!我查看了我在原始问题中输入的示例,这确实没有问题序列化不可修改的映射。我使用的ObjectMapper使用了DefaultTyping,这导致了我的问题。我已经更新了问题,现在我可以进一步缩小搜索条件。我添加了选项45.我个人同意4Thanks Perception。这对我来说非常有效。有没有一种方法可以在不返回到模型类本身的注释的情况下实现相同的行为?@hartraft您可能想要使用的是Jackson Mix-In的
    {
        "@class": "misc.stack.pojo.Account",
        "memberEmails": {
            "10": "bob@mail.com",
            "@class": "java.util.HashMap"
        }
    }