使用杰克逊反序列化可以是对象列表或对象列表的属性

时间:2019-09-25 18:16:21

标签: java jackson json-deserialization

我的库正在调用一个API,该API可以返回以下JSON结构之一-

{
  "key_is_same" : {
     "inner" : "val"
  } 
}

-或-

 {
  "key_is_same" : [{
     "inner" : "val1"
    },
    {
     "inner" : "val2"
    }
  ]
}

jakson中是否有任何注释可以处理并将其反序列化为相应类型

2 个答案:

答案 0 :(得分:1)

好像您正在寻找ACCEPT_SINGLE_VALUE_AS_ARRAY反序列化功能。

  

确定是否强制将非数组(JSON)值强制用于Java集合(数组,java.util.Collection)类型的功能。如果启用,集合反序列化器将尝试处理非数组值,就像它们对JSON数组具有“隐式”一样。出于兼容性/互操作性的原因,此功能旨在用于与仅在数组中只有一个元素的情况下忽略JSON数组的程序包(例如XML到JSON转换器)一起使用。

     

功能默认为禁用。

可以在ObjectMapper中启用它:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

或通过@JsonFormat批注:

@JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
private List<Foo> oneOrMany;

出于说明目的,请考虑以下JSON文档:

{
  "oneOrMany": [
    {
      "value": "one"
    },
    {
      "value": "two"
    }
  ]
}
{
  "oneOrMany": {
    "value": "one"
  }
}

可以反序列化为以下类:

@Data
public class Foo {
    private List<Bar> oneOrMany;
}
@Data
public class Bar {
    private String value;
}

只需确保已在您的ObjectMapper中启用了该功能,或者为您的字段加上了@JsonFormat(with = Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)注释。


如果您正在寻找用于序列化的等效功能,请参阅WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED

答案 1 :(得分:0)

我建议使用Object作为动态属性的数据类型。这是我的样本。

import java.util.Arrays;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class MainObject {

    private Object key_is_same;

    public Object getKey_is_same() {
        return key_is_same;
    }

    public void setKey_is_same(Object key) {
        this.key_is_same = key;
    }

    public static class KeyObject {
        private String inner;

        public String getInner() {
            return inner;
        }

        public void setInner(String inner) {
            this.inner = inner;
        }

    }

    public static void main(String...s) throws JsonProcessingException {
        MainObject main = new MainObject();
        KeyObject k = new KeyObject();
        k.setInner("val1");
        main.setKey_is_same(k);

        ObjectMapper om = new ObjectMapper();
        System.out.println(om.writeValueAsString(main));

        main.setKey_is_same(Arrays.asList(k, k));
        System.out.println(om.writeValueAsString(main));

        public static void main(String...s) throws IOException {
        MainObject main = new MainObject();
        KeyObject k = new KeyObject();
        k.setInner("val1");
        main.setKey_is_same(k);

        ObjectMapper om = new ObjectMapper();
        System.out.println(om.writeValueAsString(main));

        main.setKey_is_same(Arrays.asList(k, k));
        System.out.println(om.writeValueAsString(main));

        // Deserialize
        MainObject mainWithObject = om.readValue("{\"key_is_same\":{\"inner\":\"val1\"}}", MainObject.class);
        MainObject mainWithList = om.readValue("{\"key_is_same\":[{\"inner\":\"val1\"},{\"inner\":\"val1\"}]}", MainObject.class);
        if(mainWithList.getKey_is_same() instanceof java.util.List) {
            ((java.util.List) mainWithList.getKey_is_same()).forEach(System.out::println);
        }
    }
    }

}

输出

{"key_is_same":{"inner":"val1"}}
{"key_is_same":[{"inner":"val1"},{"inner":"val1"}]}