使用jackson忽略JSON对象上的未知字段

时间:2016-02-24 00:37:40

标签: jackson

我使用jackson 2.x进行序列化和反序列化。我将objectMapper注册到afterBurner模块,并将对象映射器配置为忽略未知属性

objectMapper.registerModule(new AfterBurnerModule());
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

但是当它尝试序列化一个对象时,它会因为找到属性错误

的未知字段而失败

java对象也使用@JsonIgnoreProperties注释(ignoreUnknown = true)

有人可以帮助我理解可能出现的问题吗

以下是Util类

package example;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;

public final class Util {
    private static ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.registerModule(new AfterburnerModule());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        objectMapper.setDateFormat(sdf);
        objectMapper.setAnnotationIntrospector(AnnotationIntrospector.pair(new JaxbAnnotationIntrospector(objectMapper.getTypeFactory()), new JacksonAnnotationIntrospector()));
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setSerializationInclusion(Include.NON_NULL);

    }

    private Util() {
    }

    public static <T> T convertToObject(String jsonString,Class<T> classType){
        T obj = null;
        try {
            obj = objectMapper.readValue(jsonString, classType);
        } catch (Exception e) {

        } 
        return obj;
    }

    public static String convertToString(Object obj)
            throws IOException {
        return objectMapper.writeValueAsString(obj);
    }

}

枚举类NumberEnum

package sample;

public enum NumberEnum {
ONE, TWO
}

A级

package sample;

@JsonIgnoreProperties(ignoreUnknown = true)
public class A {
@JsonProperty
    private NumberEnum number;
}

我反序列化的代码如下所示

A a = Util.convertToObject(str, A.class);

我试图取消选择的字符串如下:

{
  "number": "Num"
}

以下是反序列化时的错误:

com.fasterxml.jackson.databind.exc.InvalidFormatException:无法从String值'Num'构造sample.NumberEnum的实例:value不是声明的Enum实例名称之一:[ONE,TWO]  at(通过参考链:sample.A [“a”] - &gt; sample.NumberEnum [“number”])

A类是从jar导入的,它使用的是jackson库1.9

2 个答案:

答案 0 :(得分:5)

ignoreUnknown仅适用于目标对象中未知的属性名称。例如,如果你有:

{
  "number": "ONE",
  "foo": "bar"  
}
如果您尝试反序列化的对象没有名为“#34; foo&#34;”的setter / property,杰克逊通常会失败。

你想要完成的事情完全不同; 属性已知,但您正在尝试处理无效的枚举值。如果您只是希望将未知值反序列化为null,请使用READ_UNKNOWN_ENUM_VALUES_AS_NULL

  

允许将未知枚举值解析为空值的功能。如果禁用,未知的枚举值将抛出异常。 (...)默认情况下禁用功能。

这是通过mapper配置完成的:

objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);

注意:我刚看到您正在使用Jackson 1.9,而这个反序列化功能已在2.0中发布。如果升级不是一个选项,您可能需要为此属性创建一个自定义反序列化器,它执行相同的操作。

答案 1 :(得分:2)

我认为你需要反序列化的实际上是json,看起来像这样: { "number": "ONE" }

- 或 -

{ "number": "TWO" }

因为“Num”不是你的任何一个枚举的名称(),所以它不会反序列化