千家信息网

如何自定义JsonSerialize以及Deserialize实现数据类型转换

发表于:2025-12-01 作者:千家信息网编辑
千家信息网最后更新 2025年12月01日,如何自定义JsonSerialize以及Deserialize实现数据类型转换,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、Loca
千家信息网最后更新 2025年12月01日如何自定义JsonSerialize以及Deserialize实现数据类型转换

如何自定义JsonSerialize以及Deserialize实现数据类型转换,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

一、LocalDateTime反序列化异常

首先我们定义一个java POJO实体类,其中关键的成员变量时birthDate,我们没有采用Date数据类型,而是采用了Java8 新的日期类型LocalDateTime ,使用LocalDateTime 的好处我就不多说了,有很多的文章解释说明。我们把精力放回到Jackson的JSON格式序列化与反序列化内容上来。

[@Data](https://my.oschina.net/difrik)public class PlayerStar4 {  private String name; //姓名  private LocalDateTime birthDate; //出生日期}

下面的代码,我们首先定义了一个PlayerStar4类的对象player,然后

  • 使用writeValueAsString方法将player对象序列化为JSON字符串jsonString

  • 然后使用readValue方法将JSON字符串jsonString ,反序列化为PlayerStar4类的对象

[@Test](https://my.oschina.net/azibug)void testJSON2Object() throws IOException {  ObjectMapper mapper = new ObjectMapper();  PlayerStar4 player = new PlayerStar4();  player.setName("curry");//我并不知道库里的生日,这里是编造的  player.setBirthDate(LocalDateTime.of(1986,4,5,12,50));  //将player对象以JSON格式进行序列化为String对象  String jsonString = mapper.writeValueAsString(player);  System.out.println(jsonString);  //将JSON字符串反序列化为java对象  PlayerStar4 curry = mapper.readValue(jsonString, PlayerStar4.class);  System.out.println(curry);}

但是上面的代码报错了,从下图中可以看出

  • 将player对象序列化为JSON字符串jsonString 的过程被正常执行了,但是LocalDateTime序列化之后的结果,是图中"黄框中的黄框"内容。

  • 将JSON字符串反序列化的过程报错了,因为Jackson默认情况下,根本不认识图中"黄框中的黄框"内容这种LocalDateTime序列化之后的JSON字符串数据结构。无法把它反序列化为java对象。

怎么办?我们需要自定义序列化及反序列化类型转换器,有两种方法

  • 继承StdConverter类,自定义实现String与LocalDateTime相互转换

  • 继承JsonSerializer和JsonDeserializer类,自定义实现String与LocalDateTime相互转换

二、方法一:继承StdConverter类

继承StdConverter类,将LocalDateTime序列化为String数据类型

public class LocalDateTimeToStringConverter extends StdConverter {  static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);  @Override  public String convert(LocalDateTime value) {      return value.format(DATE_FORMATTER);  }}

继承StdConverter类,将String数据类型反序列化为LocalDateTime

public class StringToLocalDatetimeConverter extends StdConverter {  @Override  public LocalDateTime convert(String value) {      return LocalDateTime.parse(value, LocalDateTimeToStringConverter.DATE_FORMATTER);  }}

自定义的转换器完成之后,我们就可以在对应的成员变量上,使用@JsonSerialize指定序列化转换器,@JsonDeserialize指定反序列化转换器。

  @JsonSerialize(converter = LocalDateTimeToStringConverter.class)  @JsonDeserialize(converter = StringToLocalDatetimeConverter.class)  private LocalDateTime birthDate;

然后调用第一小节中的测试用例,就不会出现异常了。控制台打印输出结果如下,第一行是序列化结果JSON格式字符串,第二行是Java 对象的toString()方法的打印结果。

{"name":"curry","birthDate":"1986-4-5 12:50:00"}PlayerStar4(name=curry, birthDate=1986-04-05T12:50)

三、方法二:继承JsonSerializer和JsonDeserializer类

继承JsonSerializer类,将LocalDateTime序列化为String数据类型

public class LocalDateTimeSerializer extends JsonSerializer {  static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);  @Override  public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider provider)          throws IOException {          String s = value.format(DATE_FORMATTER);          gen.writeString(s);  }}

继承JsonDeserializer类,将String数据类型反序列化为LocalDateTime

public class LocalDatetimeDeserializer extends JsonDeserializer {  @Override  public LocalDateTime deserialize(JsonParser p, DeserializationContext ctx)          throws IOException {      String str = p.getText();      return LocalDateTime.parse(str, LocalDateTimeSerializer.DATE_FORMATTER);  }}

四、如果上面的你都没看懂

对于相对小白的读者,上面的自定义序列化及反序列化转换过程你都没懂,对于LocalDateTime的异常你也不要慌,Jackson已经给出了解决方案。

需要特别和大家强调的是LocalDateTimeSerializer和LocalDateTimeDeserializer其实并不需要我们自己去定义,因为Jackson已经帮我们定义好了。 之所以我还做了自定义的实现的介绍,是因为要为大家讲解这个自定义序列化和反序列化类型转换的实现过程,以后你再遇到其他的特殊的数据类型转换,或者LocalDateTime类型的特殊日期格式等,都可以自己来定义JsonSerialize和JsonDeserialize来实现数据类型的转换。

下面的这两个类就是Jackson已经帮我们定义好的LocalDateTimeSerializer和LocalDateTimeDeserializer。

import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;

使用方法是在对应的成员变量上,使用@JsonSerialize指定序列化转换器,@JsonDeserialize指定反序列化转换器。

@JsonSerialize(using = LocalDateTimeSerializer.class)@JsonDeserialize(using = LocalDateTimeDeserializer.class)private LocalDateTime birthDate;

执行之后的序列化和反序列化结果,和方法一、方法二自定义的实现效果是一样的。

看完上述内容,你们掌握如何自定义JsonSerialize以及Deserialize实现数据类型转换的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注行业资讯频道,感谢各位的阅读!

序列 类型 方法 数据 对象 字符 字符串 转换器 内容 结果 面的 格式 过程 变量 成员 日期 特殊 代码 更多 问题 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 校园网络安全手手抄报 利用网络管理平台建立专业数据库 电脑和服务器如何连接 杭州数据网络技术有限公司 江阴创新网络技术创新服务 软考网络安全工程师证书 苹果买软件开发票 哈利波特5服务器是什么 网络技术名片模板 网络技术服务包含哪些内容 邯郸亚尚软件开发有限公司 云数据中心网络技术和规划设计 网络安全运行与维护的题库 杭州康祺网络技术有限公司招聘 云电脑自己能不能开服务器 首选dns服务器密码是多少 计算机网络技术3年本科 个税申报显示执行数据库操作失败 数据库下载失败怎么办 甘肃庆阳网络安全会议 网络安全类专业主要学什么 访问git服务器 咸宁潜山国家森林公园数据库 数据库期末考试2010 网络安全宣传周创意 电商保险软件开发 数据库服务器 首选dns服务器密码是多少 思腾合力服务器是国内产的吗 免费软件开发平台有哪些
0