java - Jackson:如何防止字段序列化(同时保持反序列化)

标签 java json serialization jackson

我想进一步了解 this question大约是,我已经漫游了整整一个小时,但没有找到任何东西。

基本上,我想做的是在反序列化期间通过 Jackson 内部反射算法正确实例化一个属性,但在序列化时序列化相同的属性。

我知道 @JsonIgnore@JsonIgnoreProperties 但显然我似乎无法正确使用它们:当我向 jackson 提供正确的 map 时,我的属性被正确反序列化属性,但它也出现在序列化结果中,或者(当使用 @JsonIgnore 时)它没有被序列化(这是需要的),但也没有被反序列化(不需要)。

示例:

public class Foo {

    /* This is the property I want to be instanciated by Jackson upon deserialization
     * but not serialized upon serialization
     */
    private final Object bar = null;

    public Object getBar() {
        return bar;
    }
}

更糟糕的是,正如您所看到的,该属性是最终的(这就是为什么我热衷于通过反序列化在 Foo 实例化时使用 Jackson 反射能力)。我已经阅读过有关以不同方式注释 setter 和 getter 的潜在解决方案,但如果可能的话,我希望保留此属性的最终属性。 如果不可能,我会选择非最终属性(property)。

我希望答案不建议自定义序列化器/反序列化器,我的代码库目前没有这样的,如果解决方案的影响最小,那就完美了。再说一次,我不是 jackson 专家,所以如果我所要求的不可能,我显然会接受替代答案。

我还读过this thread on github但目前所建议的实现方式均未得到实际实现。

谢谢

<小时/>

编辑:让事情变得更清楚

public class Foo {

    private final String bar = null;

    public String getBar() {
        return bar;
    }

    @Override
    public String toString() {
        return bar;
    }
}


public void testMethod() throws IOException {
        String json = "{\"bar\":\"Value\"}";
        ObjectMapper mapper = new ObjectMapper();
        Foo foo = mapper.readValue(json, Foo.class);
        System.out.println(foo); // should have a bar property set to "Value"
        System.out.println(mapper.writeValueAsString(foo)); // should return an empty JSON object
}

最佳答案

我不确定这是否是一个优雅的解决方案,但你可以使用 MixIn特征。您必须创建如下所示的新界面:

interface FooMixIn {

    @JsonIgnore
    String getBar();
}

假设您的 POJO 如下所示:

class Foo {

    private final String bar = null;

    public String getBar() {
        return bar;
    }

    @Override
    public String toString() {
        return bar;
    }
}

现在您必须告诉 Jackson 您要忽略此属性:

String json = "{\"bar\":\"Value\"}";
System.out.println(json);
ObjectMapper deserializeMapper = new ObjectMapper();
deserializeMapper.addMixInAnnotations(Foo.class, FooMixIn.class);
System.out.println(deserializeMapper.readValue(json, Foo.class));

以上示例打印:

{"bar":"Value"}
null

如果程序打印上方没有 deserializeMapper.addMixInAnnotations(Foo.class, FooMixIn.class); 行:

{"bar":"Value"}
Value
<小时/>

编辑 1

<小时/>

如果你想达到你所展示的结果,你必须创建两个ObjectMapper并自定义它们。请参阅下面的示例:

String json = "{\"bar\":\"Value\"}";
ObjectMapper deserializerMapper = new ObjectMapper();
Foo foo = deserializerMapper.readValue(json, Foo.class);
System.out.println("Foo object: " + foo);

ObjectMapper serializerMapper = new ObjectMapper();
serializerMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
serializerMapper.addMixInAnnotations(Foo.class, FooMixIn.class);
System.out.println("JSON: " + serializerMapper.writeValueAsString(foo));

对于序列化,您必须使用一个实例,对于反序列化,您必须使用另一实例。

关于java - Jackson:如何防止字段序列化(同时保持反序列化),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25675011/

相关文章:

java - 方法内部类约定

java - 在 Java 中映射到 JSON

javascript - 如何在 Javascript 中解析嵌套的 JSON?

c# - 将传感器数据对象转换为字节数组 (C#)

java - 在 ImageView 上使用 setBackgroundDrawable 时出现 Eclipse 错误

java - java流中的最佳 block 大小

java - Android 中类似 facebook 的 react 按钮

android - 在 android 上的本地主机中读取简单的 Json

entity-framework - 序列化 Entity Framework 问题

xml - 二进制序列化与 JSON 与 xml