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

5

我正在使用Jackson 2.x进行序列化和反序列化。我已经将objectMapper注册到afterBurner模块,并配置了objectMapper以忽略未知属性。

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: 无法构造样本.NumberEnum的实例,其字符串值为'Num':该值不是已声明的枚举实例名称之一:[ONE,TWO] (通过引用链:sample.A [“a”] -&gt;sample.NumberEnum [“number”])

类A从一个jar包导入,并使用jackson库1.9。


你能提供更多关于错误的信息以及代码片段吗?忽略未知属性对于反序列化很重要,但是你正在尝试序列化一个对象,所以它不应该起作用。 - Mark Peters
@MarkPeters添加了更多细节。 - java2890
2个回答

9

ignoreUnknown 只适用于目标对象中未知的 属性名称。例如,如果您有以下内容:

{
  "number": "ONE",
  "foo": "bar"  
}

Jackson通常会失败,如果您尝试反序列化的对象没有名为“foo”的setter/属性。
您要完成的任务完全不同;该属性是已知的,但您正在尝试处理无效的枚举值。如果您只想将其反序列化为未知值null,请使用READ_UNKNOWN_ENUM_VALUES_AS_NULL

允许将未知的枚举值解析为null值的功能。如果禁用,则未知的枚举值将引发异常。(...)默认情况下禁用此功能。

这是通过映射器配置完成的:
objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);
注意: 我刚刚看到你正在使用Jackson 1.9版本,而这个反序列化特性是在2.0版本中发布的。如果升级不是一个选择,你可能需要为这个属性创建一个自定义的反序列化器来实现相同的功能。

1
我认为你需要反序列化的实际上是以下类似于json的内容: { "number": "ONE" } - 或者 - { "number": "TWO" } 由于"Num"不是任何一个枚举类型的名称,因此它无法进行反序列化。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接