java:java.util.BitSet对象的Jackson序列化和反序列化实现

2024-03-21 07:36

本文主要是介绍java:java.util.BitSet对象的Jackson序列化和反序列化实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

java.util.BitSet是个非常方便的比特位数据存储和操作类,一个 bit 具有2个值:0和1,正好可以用来表示 false 和 true,适用于判断“数据是否存在”的场景。
但是,这个从JDK1.0版本就存在的类,Jackson,Fastjson这些主流的JSON工具却并没有对它提供序列化和反序列化支持。
所以如果要在自己的数据结构中用到BitSet,就要自己实现序列化和反序列化。
上篇博客《java:java.util.BitSet对象的Fastjson序列化和反序列化实现》介绍了Fastjson实现,本文说明Jackson如何支持BitSet类型的序列化和反序列化
以下是BitSet对象的Jackson序列化和反序列化实现,
主要思路就是在序列化过程中将BitSet的数据转为JSON数组(如[7707,8822]或单个数字(当设置SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED特性时).
在反序列化阶段,根据TOKEN类型不同,将数据序列化为long[]再调用BitSet.valueOf方法转为BitSet对象返回。

/*** {@link BitSet} 的JACKSON序列化和反序列化实现* @author guyadong* @since 3.30.1*/
public class BitsetJacksonCodec {public static final Deserializer DESERIALIZER = new Deserializer();public static final Serializer SERIALIZER = new Serializer();/*** {@link BitSet}反序列化实现*/public static class Deserializer extends JsonDeserializer<BitSet> {private final JsonDeserializer<?> longArrayDeserializer = PrimitiveArrayDeserializers.forType(long.class);@Overridepublic BitSet deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {ObjectMapper mapper = (ObjectMapper) jp.getCodec();switch(jp.currentTokenId()) {case JsonTokenId.ID_NULL:jp.nextToken();return null;case JsonTokenId.ID_START_ARRAY:{long[] longs = (long[]) longArrayDeserializer.deserialize(jp, ctxt);return BitSet.valueOf(longs);}case JsonTokenId.ID_STRING:{/** 将文本递归解析 */String text = jp.getText();jp.nextToken();return mapper.readValue(text, BitSet.class);}default:{/** 数字类型:VALUE_NUMBER_INT */BitSet bitSet = BitSet.valueOf(new long[] {jp.getNumberValue().longValue()});jp.nextToken();return bitSet;}}}}/*** {@link BitSet}序列化实现*/public static class Serializer extends JsonSerializer<BitSet> {@SuppressWarnings({ "rawtypes" })private final JsonSerializer longArraySerializer = StdArraySerializers.findStandardImpl(long[].class);@SuppressWarnings("unchecked")@Overridepublic void serialize(BitSet value, JsonGenerator gen, SerializerProvider serializers)throws IOException, JsonProcessingException {if(null == value) {gen.writeNull();}else {longArraySerializer.serialize(value.toLongArray(), gen, serializers);}}}
}

测试及调用示例:

	@Testpublic void test5JacksonCodec() {try {BitSet bitSet = BitSet.valueOf(new byte[] {27,30});ObjectMapper mapper = new ObjectMapper();SimpleModule module = new SimpleModule().addDeserializer(BitSet.class, BitsetJacksonCodec.DESERIALIZER).addSerializer(BitSet.class, BitsetJacksonCodec.SERIALIZER);mapper.registerModule(module);{/** 序列化为数组 */ String json = mapper.writeValueAsString(bitSet);log("JSON:{}",json);assertTrue(json.equals("[7707]"));BitSet parsed = mapper.readValue(json, BitSet.class);assertTrue(bitSet.equals(parsed));}{mapper.enable(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED);/** 序列化为数字 */ String json = mapper.writeValueAsString(bitSet);log("JSON:{}",json);assertTrue(json.equals("7707"));BitSet parsed = mapper.readValue(json, BitSet.class);assertTrue(bitSet.equals(parsed));}{mapper.disable(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED);/** 序列化为数字 */ String json = mapper.writeValueAsString(new TestBean(bitSet, 32));log("JSON:{}",json);assertTrue(json.equals("{\"bitSet\":[7707],\"age\":32}"));TestBean parsed = mapper.readValue(json, TestBean.class);assertTrue(bitSet.equals(parsed.bitSet));}}catch (Throwable e) {e.printStackTrace();fail();}}public static class TestBean{BitSet bitSet;Integer age;public TestBean() {}public TestBean(BitSet bitSet, Integer age) {this.bitSet = bitSet;this.age = age;}public BitSet getBitSet() {return bitSet;}public void setBitSet(BitSet bitSet) {this.bitSet = bitSet;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}

完整实现代码参见码云仓库:https://gitee.com/l0km/sql2java/blob/dev/sql2java-base/src/main/java/gu/sql2java/json/BitsetJacksonCodec.java
完整测试代码参见码云仓库:https://gitee.com/l0km/sql2java/blob/dev/sql2java-base/src/test/java/gu/sql2java/BitSetJsonCodecTest.java

这篇关于java:java.util.BitSet对象的Jackson序列化和反序列化实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/832098

相关文章

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

分布式锁在Spring Boot应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.