杰克逊:如何防止现场序列化(同时保持反序列化) [英] Jackson: how to prevent field serialization (while keeping deserialization)

查看:125
本文介绍了杰克逊:如何防止现场序列化(同时保持反序列化)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想进一步了解这个问题的内容我现在一直在漫游SO,没有找到任何东西。

I'd like to go further on what this question was about, I've been roaming SO for a solid hour now without finding anything.

基本上,我要做的就是通过杰克逊的内部反思来妥善安置一个房产反序列化期间的算法,但在序列化时具有相同的属性序列化。

Basically, what I'm trying to do is having a property properly instanciated through Jackson internal reflection algorithm during deserialization but having this same property not serialized when it comes to serialization.

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

I know about @JsonIgnore and @JsonIgnoreProperties but apparently I can't seem to use them right : either my property is correctly deserialized when I feed Jackson a proper map of properties but it also appears in the serialized results, either (when using @JsonIgnore) it is not serialized (which is wanted) but also not deserialized (not wanted).

示例:

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的潜在解决方案,但我想尽可能保持这个属性为final。 如果不可能,我会选择非最终财产。

To make things worse, as you can see, the property is final (this is why I'm keen on using Jackson reflection ability upon Foo instanciation through deserialization). I've read on potential solution about annotating the setter and the getter differently but I'd like to keep this property final if possible. If not possible, I'd settle for a non-final property.

我很感激答案不建议使用自定义序列化器/解串器,我的代码基地目前是免费的,如果解决方案影响最小,那将是完美的。再说一遍,我不是杰克逊的专家,所以如果我问的是不可能,我显然会接受其他答案。

I would appreciate answers not suggesting custom serializer/deserializer, my code base is currently free of such and if the solution could be of minimal impact, that would be perfect. Again, I'm no Jackson expert so if what I'm asking is not possible I'll obviously accept alternative answers.

我也读过 github上的这个主题但目前实际上并未实施任何建议的实施方式。

I've also read this thread on github but none of the suggested ways of implementation have actually been implemented at the moment.

谢谢

编辑:让事情更清晰

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 功能。你必须创建一个新界面,如下所示:

I am not sure whether it is elegant solution but you can use MixIn feature. You have to create new interface which could look like below:

interface FooMixIn {

    @JsonIgnore
    String getBar();
}

假设你的 POJO 看起来像这样:

Assume that your POJO looks like this:

class Foo {

    private final String bar = null;

    public String getBar() {
        return bar;
    }

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

现在你必须告诉杰克逊你要忽略这个属性:

Now you have to tell Jackson that you want to ignore this property:

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); 上面的程序打印行:

Without deserializeMapper.addMixInAnnotations(Foo.class, FooMixIn.class); line above program prints:

{"bar":"Value"}
Value






编辑1

如果你想实现结果就像你表明你必须创建两个 ObjectMapper 并自定义它们。见下面的例子:

If you want to achieve result like you showed you have to create two ObjectMappers and customize them. See below example:

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));

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

For serialization you have to use one instance and for deserialization you have to use another instance.

这篇关于杰克逊:如何防止现场序列化(同时保持反序列化)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆