如何在Jackson中为通用类型创建自定义解串器?

克雷西米尔·内塞克(KrešimirNesek)

想象以下情况:

class <T> Foo<T> {
    ....
}

class Bar {
    Foo<Something> foo;
}

我想为Foo写一个自定义的Jackson解串器。为了做到这一点(例如,为了反序列化Bar类,它具有Foo<Something>属性),我需要知道的具体类型Foo<T>,在使用Bar,在反序列化时间(比如我需要知道TSomething在particluar情况下)。

一个人怎么写这样的反序列化器?因为杰克逊使用类型化的集合和地图来做到这一点,所以应该有可能做到这一点。

说明:

似乎有两个部分可以解决问题:

1)获取foo内部声明的属性类型Bar并使用其反序列化Foo<Somehting>

2)在反序列化时发现我们正在对foo类内部的属性进行反序列化Bar,以便成功完成步骤1)

一个如何完成1和2?

不同地

您可以JsonDeserializer为自己的通用类型实现自定义该自定义类型也可以实现ContextualDeserializer

例如,假设我们具有以下包含通用值的简单包装器类型:

public static class Wrapper<T> {
    public T value;
}

现在,我们要反序列化如下所示的JSON:

{
    "name": "Alice",
    "age": 37
}

变成一个看起来像这样的类的实例:

public static class Person {
    public Wrapper<String> name;
    public Wrapper<Integer> age;
}

实现ContextualDeserializer使我们能够Person基于字段的通用类型参数为类中的每个字段创建特定的反序列化器这使我们可以将名称反序列化为字符串,将年龄反序列化为整数。

完整的解串器如下所示:

public static class WrapperDeserializer extends JsonDeserializer<Wrapper<?>> implements ContextualDeserializer {
    private JavaType valueType;

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
        JavaType wrapperType = property.getType();
        JavaType valueType = wrapperType.containedType(0);
        WrapperDeserializer deserializer = new WrapperDeserializer();
        deserializer.valueType = valueType;
        return deserializer;
    }

    @Override
    public Wrapper<?> deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException {
        Wrapper<?> wrapper = new Wrapper<>();
        wrapper.value = ctxt.readValue(parser, valueType);
        return wrapper;
    }
}

最好先看createContextual这里,因为这将由杰克逊首先调用。我们从中读取字段的类型BeanProperty(例如Wrapper<String>),然后提取第一个通用类型参数(例如String)。然后,我们创建一个新的反序列化器并将内部类型存储为valueType

一旦deserialize调用了这个新创建的反序列化器,我们可以简单地要求Jackson将值反序列化为内部类型而不是整个包装器类型,然后返回一个Wrapper包含反序列化值的新值。

为了注册此自定义反序列化器,我们需要创建一个包含它的模块,然后注册该模块:

SimpleModule module = new SimpleModule()
        .addDeserializer(Wrapper.class, new WrapperDeserializer());

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(module);

然后,如果我们尝试从上面反序列化示例JSON,则可以看到它按预期工作:

Person person = objectMapper.readValue(json, Person.class);
System.out.println(person.name.value);  // prints Alice
System.out.println(person.age.value);   // prints 37

Jackson文档中,有更多有关上下文反序列化器如何工作的详细信息

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Jackson的自定义解串器中调用默认解串器?

来自分类Dev

如何在Jersey / Jackson中创建用于设置对象的自定义设置器?

来自分类Dev

自定义Jackson解串器未在春季注册

来自分类Dev

如何在Go中创建自定义类型元素的自定义类型数组?

来自分类Dev

如何在Laravel中为字符串字段创建自定义自动增量

来自分类Dev

如何在mvc中为文本框创建自定义html帮助器

来自分类Dev

如何在Ember中创建自定义枚举器?

来自分类Dev

如何在Grails中注册自定义json解串器/解析器?

来自分类Dev

如何在MC查看器中为文件类型添加自定义解析器?

来自分类Dev

如何在 umbraco 中创建表示自定义数据类型列表的自定义数据类型?

来自分类Dev

如何在Spray JSON中为布尔类型实现自定义反序列化器

来自分类Dev

如何在Android中为颜色创建选择器(例如颜色状态列表,但用于自定义属性)?

来自分类Dev

如何在旧版编译器中为自定义语言创建自己的旧版语言模板?

来自分类Dev

如何在自定义Eclipse编辑器中为语法错误创建错误悬停

来自分类Dev

如何在 actionscript 3.0 中为音乐播放器创建一个简单的自定义搜索栏

来自分类Dev

如何在F#中为自定义类型定义一元减号?

来自分类Dev

在Python中创建自定义字符串类型

来自分类Dev

在Python中创建自定义字符串类型

来自分类Dev

如何在 Wordpress 中为自定义帖子类型加载自定义样式表?

来自分类Dev

如何在Spring Boot 1.4中自定义Jackson

来自分类Dev

如何在Odoo上为自定义值创建控制器?

来自分类Dev

如何使用 ACF 为自定义帖子类型创建自定义端点?

来自分类Dev

在Groovy中为地图创建自定义比较器

来自分类Dev

如何在Drupal 7中为自定义内容类型添加主题/编辑表单

来自分类Dev

如何在此 marqup 中为自定义帖子类型编写循环

来自分类Dev

如何在 mac osx 中为文件类型设置自定义图标

来自分类Dev

如何在Mockito中创建自定义数据类型列表的模拟?

来自分类Dev

如何在php中创建自定义数据类型?

来自分类Dev

如何在Java中创建自定义数据类型的HashSet?

Related 相关文章

  1. 1

    如何在Jackson的自定义解串器中调用默认解串器?

  2. 2

    如何在Jersey / Jackson中创建用于设置对象的自定义设置器?

  3. 3

    自定义Jackson解串器未在春季注册

  4. 4

    如何在Go中创建自定义类型元素的自定义类型数组?

  5. 5

    如何在Laravel中为字符串字段创建自定义自动增量

  6. 6

    如何在mvc中为文本框创建自定义html帮助器

  7. 7

    如何在Ember中创建自定义枚举器?

  8. 8

    如何在Grails中注册自定义json解串器/解析器?

  9. 9

    如何在MC查看器中为文件类型添加自定义解析器?

  10. 10

    如何在 umbraco 中创建表示自定义数据类型列表的自定义数据类型?

  11. 11

    如何在Spray JSON中为布尔类型实现自定义反序列化器

  12. 12

    如何在Android中为颜色创建选择器(例如颜色状态列表,但用于自定义属性)?

  13. 13

    如何在旧版编译器中为自定义语言创建自己的旧版语言模板?

  14. 14

    如何在自定义Eclipse编辑器中为语法错误创建错误悬停

  15. 15

    如何在 actionscript 3.0 中为音乐播放器创建一个简单的自定义搜索栏

  16. 16

    如何在F#中为自定义类型定义一元减号?

  17. 17

    在Python中创建自定义字符串类型

  18. 18

    在Python中创建自定义字符串类型

  19. 19

    如何在 Wordpress 中为自定义帖子类型加载自定义样式表?

  20. 20

    如何在Spring Boot 1.4中自定义Jackson

  21. 21

    如何在Odoo上为自定义值创建控制器?

  22. 22

    如何使用 ACF 为自定义帖子类型创建自定义端点?

  23. 23

    在Groovy中为地图创建自定义比较器

  24. 24

    如何在Drupal 7中为自定义内容类型添加主题/编辑表单

  25. 25

    如何在此 marqup 中为自定义帖子类型编写循环

  26. 26

    如何在 mac osx 中为文件类型设置自定义图标

  27. 27

    如何在Mockito中创建自定义数据类型列表的模拟?

  28. 28

    如何在php中创建自定义数据类型?

  29. 29

    如何在Java中创建自定义数据类型的HashSet?

热门标签

归档