Jackson 2.6.3反序列化避免将文字null添加到集合中

时间:2015-11-05 19:51:43

标签: java json jackson deserialization

我正在尝试使用Jackson 2.6.3反序列化json上下文。我在json内容中有null literal,如下所示。我试图避免将其添加到反序列化的集合中。请参阅下面的输出。我在mapper上尝试了各种配置选项。但是我无法避免集合中的null对象。任何解决问题的指针都欢迎。

我在stackoverflow中看到了许多类似的问题,如下所示,但所有这些问题都与自定义反序列化类中的各个属性有关,而不是集合中的元素。

How to deserialize JSON null to a NullNode instead of Java null?

JSON内容(Data.txt)

{
  "myList": [
  {
     "type": "1"
  },
  {
     "type": "2"
  },
  null
  ]
}

RootObject.java

@JsonInclude(Include.NON_NULL)
public class RootObject {

private List<Types> myList;

public List<Types> getMyList() {
    return myList;
}

public void setMyList(List<Types> myList) {
    this.myList = myList;
}

public String toString(){
    return new ReflectionToStringBuilder(this).toString();
}
}

Types.java

@JsonInclude(Include.NON_NULL)
public class Types {

private String type;

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public String toString(){
    return new ReflectionToStringBuilder(this).toString();
}
}

JacksonTester

public class JacksonTester2 {

    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.getSerializationConfig().withSerializationInclusion(Include.NON_EMPTY);
        mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
        RootObject rootObject = null;
        try {
            rootObject = mapper.readValue(new File("Data.txt"), RootObject.class);
        } catch (Exception e) {
            e.printStackTrace();
        } 
        System.out.println(rootObject);
    }
    }

输出

RootObject@1a74681a[myList=[Types@ace10d9[type=1], Types@5eb41c19[type=2], null]]

3 个答案:

答案 0 :(得分:0)

我从以下帖子中获得灵感

Jackson: Ignore whitespace in empty @XmlWrapperElement collection

以下是针对上述问题的解决方案

public class NullCollectionHandler extends SimpleModule {
    private static class CustomizedCollectionDeserialiser extends CollectionDeserializer {

        public CustomizedCollectionDeserialiser(CollectionDeserializer src) {
            super(src);
        }

        private static final long serialVersionUID = 1L;

        @Override
        public Collection<Object> deserialize(JsonParser jp, DeserializationContext ctxt)
                throws IOException, JsonProcessingException {
            Collection<Object> oldCol = super.deserialize(jp, ctxt);
            Collection<Object> newCol = new ArrayList<Object>();
            if(CollectionUtils.isNotEmpty(oldCol)){
                for(Object obj : oldCol){
                    if(obj != null)
                    newCol.add(obj);
                }
            }
            return newCol;
        }

        @Override
        public CollectionDeserializer createContextual(DeserializationContext ctxt,
                BeanProperty property) throws JsonMappingException {
            return new CustomizedCollectionDeserialiser(super.createContextual(ctxt, property));
        }
    }

    private static final long serialVersionUID = 1L;

    @Override
    public void setupModule(SetupContext context) {
        super.setupModule(context);
        context.addBeanDeserializerModifier(new BeanDeserializerModifier() {
            @Override
            public JsonDeserializer<?> modifyCollectionDeserializer(
                    DeserializationConfig config, CollectionType type,
                    BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
                if (deserializer instanceof CollectionDeserializer) {
                    return new CustomizedCollectionDeserialiser(
                        (CollectionDeserializer) deserializer);
                } else {
                    return super.modifyCollectionDeserializer(config, type, beanDesc,
                        deserializer);
                }
            }
        });
    }
}

答案 1 :(得分:0)

没有办法以这种方式直接修改数组反序列化。但是一种相对简单的方法可能是定义一个Converter,它需要Collection(或List)预期类型,返回相同的内容并使用:

@JsonDeserialize(converter=MyConverter.class)

表示它应该用作反序列化的一部分。这样做是让Jackson使用默认逻辑反序列化Collection,然后您的转换器可以遍历它并删除null个条目(或者如果您愿意,还可以创建一个新的Collection。) p>

或者,您可以创建自定义Collection / List子类型,并覆盖其add()方法以静默方式删除null,但通过super.add(value)传递其他值}。这将是最有效的方法,甚至可能是最简单的方法。 您甚至可以将属性类型声明为简单Collection,但指定实际使用的子类型:

@JsonDeserialize(as=NoNullsCollection.class)
public List<String> names;

答案 2 :(得分:-1)

您可以将ObjectMapper配置为忽略NULL,如下所示:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializationInclusion(Include.NON_NULL);

或者您可以使用以下注释:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)