是否可以在类级别为不同的数据类型配置 Jackson 自定义反序列化器?

2023-12-14

我需要反序列化一个又长又复杂的json,我为此编写了一组java类来映射数据,并且我必须为许多不同类型的字段编写自定义反序列化器(包括String、Boolean、BigDecimal等).

我知道我可以使用相应的自定义反序列化器注释 java 类中的所有字段(如下所示),但随后我需要注释所有类中的几乎所有字段。

@JsonDeserialize(using = CustomBooleanJsonDeserializer.class)
private boolean active;

我还知道我可以在Spring默认中注册一个模块ObjectMapper (like here),但我只想将这些自定义反序列化器用于这些特定的类。

@Bean
public Module customDeserializersModule() {
    SimpleModule module = new SimpleModule();
    module.addDeserializer(Boolean.class, new CustomBooleanJsonDeserializer());
    // add other custom deserializers 
    return module;
}

我什至知道我可以使用自定义ObjectMapper in the RestController,但我不想放弃通过自动数据绑定的便利@RequestBody,因为我必须防止其他人在没有必要的自定义反序列化器的情况下使用它。

@RequestMapping(method = RequestMethod.POST, value = "/data")
public ResponseEntity<ServerInfo> register(@RequestBody DataMapper data) {
   // DataMapper is the target POJO class of the json's deserialization
}

简而言之,我正在班级层面寻找类似的东西:

@JsonDeserialize(using = CustomStringJsonDeserializer.class, forType = String.class)
@JsonDeserialize(using = CustomBooleanJsonDeserializer.class, forType = Boolean.class)
@JsonDeserialize(using = CustomBigDecimalJsonDeserializer.class, forType = BigDecimal.class)
public class DataMapper implements Serializable {
    // obviously, @JsonDeserialize doesn't have a forType method
}

或者也许有某种方式实现自定义解串器为了DataMapper类,定义如何根据其数据类型反序列化每个字段(无需注释每个字段):

@JsonDeserialize(using = DataMapperJsonDeserializer.class)
public class DataMapper implements Serializable {
    // How can I implement the DataMapperJsonDeserializer with these 
    // characteristics? I know about the ContextualDeserializer interface, 
    // but I don't know how to use it without annotating each field.
}

或某种方式将模块的效果限制为一个包或一组类:

module.restrictedTo(/*some package or set of classes*/);
// com.fasterxml.jackson.databind.Module doesn't have a restrictedTo method

您可以为该类定义自定义反序列化器(作为问题中的第二个想法)并使用您自己的自定义ObjectMapper inside:

public class DataMapperJsonDeserializer extends JsonDeserializer<DataMapper> {

    private static final ObjectMapper objectMapper = new ObjectMapper();
    private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");

    static {
        SimpleModule module = new SimpleModule();
        module.addDeserializer(BigInteger.class, new CustomBigIntegerJsonDeserializer());
        module.addDeserializer(BigDecimal.class, new CustomBigDecimalJsonDeserializer());
        module.addDeserializer(Boolean.class, new CustomBooleanJsonDeserializer());
        module.addDeserializer(String.class, new CustomStringJsonDeserializer());
        objectMapper.registerModule(module);
        objectMapper.addMixIn(DataMapper.class, DefaultJsonDeserializer.class);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setDateFormat(simpleDateFormat);
    }

    @Override
    public DataMapper deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        return objectMapper.readValue(jsonParser, DataMapper.class);
    }

    @JsonDeserialize
    private interface DefaultJsonDeserializer {
        // Reset default json deserializer
    }

}

注意使用Jackson 混合注释 (the DefaultJsonDeserializer 界面)从动态删除自定义解串器POJO类,避免StackOverflowError否则会由于以下原因而被抛出objectMapper.readValue(jsonParser, DataMapper.class).


然后,只需注释POJO class:

@JsonDeserialize(using = DataMapperJsonDeserializer.class)
public class DataMapper implements Serializable {
    // It is not necessary to annotate each field with custom deserializers.
}

您甚至可以添加其他POJO类作为领域DataMapper并且每种类型的自定义反序列化器将自动应用于其字段,而不需要注释。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否可以在类级别为不同的数据类型配置 Jackson 自定义反序列化器? 的相关文章

  • 使用 .NET 2.0 解析 JSON

    想要改进这篇文章吗 提供此问题的详细答案 包括引用和解释为什么你的答案是正确的 不够详细的答案可能会被编辑或删除 我有一个用 C 编写的应用程序 带有 NET Framework 2 0 版本 不幸的是 我无法选择更新到较新版本的 NET
  • 寻找 WebElements,最佳实践

    在我们当前的自动化 使用 Selenium WebDriver Java 中 我们使用 FindBy very广泛地 例如 FindBy css a name bcrumb protected List
  • 如何使用 Gradle 2.10 将 ANTLR 词法分析器语法导入到另一个语法中?

    我一直在和 Terence Parr 一起学习 ANTLR 4权威的 ANTLR 4 参考 到目前为止我一直在使用 Gradle 2 10 及其内置 ANTLR 插件进行跟踪 然而 我在获取一些我从第 4 章第 38 41 页改编的代码以使
  • 向对象添加元素

    我需要填充一个 json 文件 现在我有这样的东西 element id 10 quantity 1 我需要添加另一个 元素 我的第一步是使用该 json 将该 json 放入对象类型中cart JSON parse 现在我需要添加新元素
  • 为什么不能将 String 添加到 List 类型?

    错误 The method add capture 1 of in the type List
  • 如何使用java避免Mysql数据库中的“数据因列被截断”?

    在我的 Java 程序中 Hibernate Bean 类定义一列 例如 TimtableVO java Column name REPEAT DAYS private WeekdayType repeatDays hear Weekday
  • Stream#limit 返回的元素是否可以少于预期?

    如果流s下面至少有n元素 流在什么情况下sLimit可能少于n元素 如果有的话 Stream sLimit s limit n 提问原因 在这个答案 https stackoverflow com a 28082107 829571 我读到
  • AIX:IBM Java:java.net.SocketException:连接超时:可能是由于地址无效

    当尝试与我们的服务器建立 SSL 连接时 我们在 IBM AIX 上经常看到以下异常 java net SocketException Socket closed at com sun net ssl internal ssl SSLSoc
  • Java中通过FTP创建文件夹层次结构

    Java 是否有现成的功能可以在远程 FTP 服务器上创建文件夹层次结构 Apache Commons 确实提供了 FTP 客户端 但我找不到创建目录层次结构的方法 它确实允许创建单个目录 makeDirectory 但创建整个路径似乎并不
  • Ubuntu 的打包 - Web 应用程序

    Web 应用程序没有与 C 或类似文件不同的 make 文件 但是 它需要放置在特定的目录中 例如 var www 我是 Linux 打包新手 所以我的问题是 如何将我的应用程序打包到 deb 中 以便在安装时将其放入 etc myprog
  • 创建一个 int 类型的随机数组。爪哇

    我需要创建一个随机的 int 数组 并按我自己的类对其进行排序 这是我制作数组的地方 public class MyProgram9 public static void main String args int list new int
  • 使用java读取Excel工作表的单列

    我有一张 Excel 表格 我想编写一个方法 该方法将参数作为要读取的列号 并返回一个由该列中的所有数据组成的数组 然后将该列元素放置在 xml 工作表中 我怎样才能编写一个方法来做到这一点 使用 Apache POI 您可以在他们的使用页
  • 在Java中使用==而不是equals来比较不可变对象可以吗

    考虑调用静态工厂方法 valueOf 的两个 Integer 类型的引用 如下所示 Integer a Integer valueOf 10 Integer b Integer valueOf 10 考虑到Integer是不可变的 使用 而
  • 将 @RequestLine 与 Feign 一起使用

    我有一个工作 Feign 接口定义为 FeignClient content link service public interface ContentLinkServiceClient RequestMapping method Requ
  • 当另一个线程发生事情时从主线程获取数据?

    目前我有一个线程正在运行一个侦听连接的套接字 当它收到连接时 它需要上传在主线程中收集的数据 即从主线程获取数据 但是 我传递了对象的实例 但它从未使用等待连接时收集的数据进行更新 有没有正确的方法来做到这一点 我用谷歌搜索了一下 似乎找不
  • Java 8 Stream - 为什么过滤器方法不执行? [复制]

    这个问题在这里已经有答案了 我正在学习使用java流进行过滤 但是过滤后的流没有打印任何内容 我认为过滤器方法没有被执行 我的过滤代码如下 Stream of d2 a2 b1 b3 c filter s gt s startsWith b
  • 如何在jpa中共享EntityManagerFactory

    我是 jpa 的新手 这是场景 我正在开发一个 Web 应用程序 其中 多个用户可以登录 当 user1 注销时 我正在使用下面的代码 public static void closeEntityManagerFactory if enti
  • 使用 Tomcat 和 gradle 进行休眠

    免责声明 我是 Java 新手 我正在尝试使用 Tomcat 和 Gradle 设置 Hibernate 构建运行正确 但看起来像persistence xml文件未被读取 我的项目结构如下 build gradle src main ja
  • Admob - 没有广告可显示

    你好 我尝试制作一些在 Android 手机上显示广告的示例程序 并尝试在 v2 2 的模拟器上测试它 代码中的一切似乎都很好 但调试器中的 AdListener 表示 响应消息为零或空 onFailedToReceiveAd 没有广告可显
  • 用于从链表中删除元素的大 O 表示法[重复]

    这个问题在这里已经有答案了 我正在阅读有关链接列表的内容 我发现 从链表中删除所需的元素需要 O n 运行时间 其中 n 是元素的数量 列表中的元素 http www cs mcgill ca dprecup courses IntroCS

随机推荐