2014-09-04 249 views
1

我想进一步了解什么是this question,我一直漫游在一个坚实的小时现在没有找到任何东西。杰克逊:如何防止字段序列化(同时保持反序列化)

基本上,我试图做的是在反序列化过程中通过杰克逊内部反射算法正确实例化一个属性,但在序列化时有相同的属性而不是序列化。

我知道@JsonIgnore@JsonIgnoreProperties但显然我似乎无法正确使用:当我喂杰克逊性质的适当的地图无论是我的财产是正确的反序列化,但它也出现在序列化结果,或者(当使用@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 instanciation很热衷于使用杰克逊反射能力,通过反序列化)。我已经阅读了有关注解setter和getter的潜在解决方案,但是如果可能的话,我想保留此属性。 如果不可能,我会解决非最终财产。

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

我也读过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 
} 

回答

2

我不知道它是否是优雅的解决方案,但你可以使用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 S和定制他们。看下面的例子:

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

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

+0

该死的! +1,因为你的回答完全符合你描述的内容,并将我介绍给Jackson的MixIn,但它也让我意识到我已经将序列化/反序列化过程混淆了><我编辑了我的问题,如果你知道任何方式,例如回答我的问题真正的需要,我会很乐意接受你的答案。 – m4rtin 2014-09-05 11:21:38

+0

现在我真的不明白你想做什么。你想在序列化过程中隐藏这个属性,并且'Jackson'应该能够反序列化它。这是真的吗?我想提供帮助,但是你必须告诉我你的'POJO'和'JSON'是怎么样的,并且你必须告诉我你是如何序列化它的(使用JSON输出)并对它进行反序列化。好的例子会超过1000字。 – 2014-09-05 19:57:12

+0

是的,这正是我想要做的,对不起,我的问题首先不够清楚。我编辑它来反映你的例子。让我们一致认为*反序列化*过程意味着从JSON字符串到Foo实例以及从Foo实例到JSON字符串的序列化*过程。 – m4rtin 2014-09-07 12:53:49