2011-04-18 130 views
8

从JSON使用Jackson库进行反序列化时,以自定义方式实例化bean(而不是通过调用默认构造函数)的最佳和最简单的方法是什么?我发现我可以实现的接口有JsonDeserializer,但我不太确定如何将它们连接到ObjectMapper如何用Jackson自定义方式实例化bean?

UPDATE#1:我想我的问题需要更多的细节。默认情况下,Jackson的反序列化器使用默认的构造函数来创建bean。我希望能够通过调用外部工厂来实现bean的实例化。所以我需要的只是一个需要实例化的bean的类。工厂将返回可以提供给杰克逊的物业人口的实例等等。

请注意,我并不担心创建简单/标量值(如字符串或数字),只有这些bean位于我感兴趣的区域。

回答

0

你把解串器的Java对象,你想要得到的JSON映射到:

@JsonDeserialize(using = PropertyValueDeserializer.class) 
public class PROPERTY_VALUE implements Serializable{ 

然后在解串器,你可以如这样做:

@Override 
public PROPERTY_VALUE deserialize(JsonParser jsonParser, 
        DeserializationContext deserializationContext) 
      throws IOException, JsonProcessingException { 

    String tmp = jsonParser.getText(); // { 
    jsonParser.nextToken(); 
    String key = jsonParser.getText(); 
    jsonParser.nextToken(); 
    String value = jsonParser.getText(); 
    jsonParser.nextToken(); 
    tmp = jsonParser.getText(); // } 

    PROPERTY_VALUE pv = new PROPERTY_VALUE(key,value); 
    return pv; 
} 

如果你不想使用注释,你需要通过映射器DeserializerProvider,可以提供给定类型的正确解串器。

mapper.setDeserializerProvider(myDeserializerProvider); 

对于构造 - 当然,你可以通过调用解串器内的工厂产生的目标等级:

String value = jsonParser.getText(); 
    jsonParser.nextToken(); 
    tmp = jsonParser.getText(); // } 

    MyObject pv = MyObjectFactory.get(key); 
    pv.setValue(value); 
    return pv; 
} 

但后来我可能误解了您的更新

+0

谢谢Heiko。杰克逊默认使用bean的默认构造函数来创建实例。我想要做的是通过使用外部工厂实际创建bean。我会稍后更新一些细节。 – 2011-04-18 10:08:00

+0

如何在不使用注释的情况下做到这一点? – 2011-04-18 10:13:30

+1

通过使用混合注释,它不需要直接添加到类本身,而是添加到其他“混合”类。这使得使用第三方库的注解方法成为可能。 – StaxMan 2011-04-18 22:51:09

8

一些事情,可能会帮助...

首先,您可以使用@JsonCreator来定义要使用的替代构造函数(所有参数都必须使用@JsonProperty进行注释,因为字节码有没有名字),或者一个静态工厂。它仍然是值类的一部分,但可以帮助支持不可变对象。其次,如果你想要真正的自定义反序列化过程,你可以看看http://wiki.fasterxml.com/JacksonHowToCustomDeserializers,它解释了如何注册自定义反序列化器。

杰克逊目前错过的一件事是支持构建器样式的对象;有一项增加支持的功能请求(并且计划是在开发者有时间之后在未来添加支持)。

相关问题