如何使用 Jackson 以自定义方式实例化 bean?

发布于 2024-11-02 04:24:00 字数 352 浏览 2 评论 0原文

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

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

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

What is the best and easiest way to instantiate beans in custom way (not by calling default constructor) while deserializing from JSON using Jackson library? I found that there is JsonDeserializer interface that I could implement, but I'm not too sure how to wire it all together into the ObjectMapper.

UPDATE #1: I think some more details is required for my question. By default Jackson's deserializer uses default constructor to crete beans. I'd like to be able to implement instantiation of the bean by calling external factory. So what I need is just a class of the bean that needs to be instantiated. The factory will return instance that can then be provided to Jackson for property population and so on.

Please note that I'm not concerned about creation of simple/scalar values such as strings or numbers, only the beans are in the area of my interest.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风轻花落早 2024-11-09 04:24:00

有些事情可能会有所帮助...

首先,您可以使用 @JsonCreator 定义要使用的备用构造函数(所有参数都必须用 @JsonProperty 注释,因为字节码没有名称)或静态工厂。它仍然是值类的一部分,但可以帮助支持不可变对象。

其次,如果您想要真正的自定义反序列化过程,您可以查看 https://github。 com/FasterXML/jackson-docs/wiki/JacksonHowToCustomSerializers 解释了如何注册自定义反序列化器。

Jackson 目前缺少的一件事是对构建器风格对象的支持;有一个添加支持的功能请求(计划是在开发人员有时间的情况下在将来添加支持)。

Some things that may help...

First, you can use @JsonCreator to define alternate constructor to use (all arguments must be annotated with @JsonProperty because bytecode has no names), or a static factory. It would still be part of value class, but can help support immutable objects.

Second, if you want truly custom deserialization process, you can check out https://github.com/FasterXML/jackson-docs/wiki/JacksonHowToCustomSerializers which explains how to register custom deserializers.

One thing that Jackson currently misses is support for builder-style objects; there is a feature request to add support (and plan is to add support in future once developers have time).

无需解释 2024-11-09 04:24:00

您将反序列化器放在想要将 json 映射到的 Java 对象上:

@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;
}

但是我可能误解了您的更新

You put the deserializer on the Java object you want to get the json mapped into:

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

and then in the Deserializer you can e.g. do:

@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;
}

If you don't want to use annotations, you need to pass the mapper a DeserializerProvider that can provide the right deserializer for a given type.

mapper.setDeserializerProvider(myDeserializerProvider);

For the constructors - of course you can generate the target class by calling a factory within the deserializer:

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

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

But then I may have misunderstood your update

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文