Jackson的序列化及反序列化【@JsonValue及@JsonCreator注解】

2024-04-14 15:18

本文主要是介绍Jackson的序列化及反序列化【@JsonValue及@JsonCreator注解】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Jackson的序列化

@JsonValue注解

@JsonValue 可以用在get方法或者属性字段上,一个类只能用一个,当加上@JsonValue注解时,序列化时只返回这一个字段的值,而不是这个类的属性键值对。

Teacher.class

package org.zpli.springdemo.bean;import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
import lombok.Setter;/*** created at 2021/6/3 3:38 下午** @author somnuszpli*/
@Setter
@Getter
public class Teacher {// @JsonValueString name;int age;String address;}

测试方法:

@Test
public void test2() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();Teacher teacher = new Teacher();teacher.setName("somnuszpli");teacher.setAge(24);teacher.setAddress("China");String teacherStr = mapper.writeValueAsString(teacher);System.out.println(teacherStr);
}

输出结果:

{"name":"somnuszpli","age":24,"address":"China"}

在Teacher类的name属性上添加@JsonValue 注解

package org.zpli.springdemo.bean;import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
import lombok.Setter;/*** created at 2021/6/3 3:38 下午** @author somnuszpli*/
@Setter
@Getter
public class Teacher {@JsonValueString name;int age;String address;}

运行测试方法,输出结果为:

"somnuszpli"

Jackson的反序列化

一、Jackson反序列化过程做了什么?

对于Jackson的JSON数据格式,反序列化过程就是将JSON字符串反序列化为java 对象

ObjectMapper mapper = new ObjectMapper();//将JSON字符串反序列化为java对象
String jsonInString = "{\"name\":\"乔丹\",\"age\":45,\"hobbies\":[\"高尔夫球\",\"棒球\"]}";
PlayerStar jordan = mapper.readValue(jsonInString, PlayerStar.class);System.out.println(jordan);

默认情况下,Jackson在反序列化过程中调用了哪些函数,给大家介绍一下

  • 首先调用反序列化的目标类PlayerStar的无参构造函数,构造一个java对象
  • 然后调用该类的成员变量的set方法,为该对象的每一个成员变量赋值。

所以默认情况下,一个Java类使用Jackson做反序列化,必须有public无参构造函数(java中不写也默认有),必须有成员变量的set方法。

二、@JsonCreator注解

默认情况下,Jackson的反序列化过程是上面描述的那样,默认选择类的无参构造函数创建类对象并使用setter方法给属性赋值,当没有无参构造函数时会报错。除此之外,我们还可以使用@JsonCreator注解自定义反序列化的过程,在我们自定义的反序列化函数里面,我们有更强的灵活性,可以完成更多的非规定动作。使用@JsonCreator注解的参数前面需要加上@JsonProperty,否则会报错。一共有两种自定义反序列化渠道:

  • @JsonCreator注解加在构造方法上
  • @JsonCreator注解加在工厂静态方法上

使用了@JsonCreator注解之后,将使用该注解标注的方法进行反序列化对象的构造,默认的使用无参构造函数及set方法进行反序列化的过程失效。

2.1.@JsonCreator注解加在构造方法上

该PlayerStar对应的JSON字符串是第一小节中的jsonInString。下文的构造函数,你希望将哪些属性值赋值给java 对象的成员变量,你就使用@JsonProperty("salary")去定义它。

package org.zpli.springdemo.bean;import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;/*** created at 2021/6/3 3:14 下午** @author somnuszpli*/
public class PlayerStar {private String name;private Integer age;private String[] hobbies;               // 业余爱好,数组private List<String> friends;           // 朋友private Map<String, BigDecimal> salary; // 年收入 Map//这段是我们的核心代码,使用JsonCreator注解说明该方法是反序列化构造方法。@JsonCreatorpublic PlayerStar(@JsonProperty("name") String name,@JsonProperty("age") Integer age,@JsonProperty("hobbies") String[] hobbies,@JsonProperty("friends") List<String> friends,@JsonProperty("salary") Map<String, BigDecimal> salary) {this.name = name;this.age = age;this.hobbies = hobbies;this.friends = friends;this.salary = salary;}@Overridepublic String toString() {return "PlayerStar{" +"name='" + name + '\'' +", age=" + age +", hobbies=" + Arrays.toString(hobbies) +", friends=" + friends +", salary=" + salary +'}';}
}

我们使用第一小节中的反序列化代码,将jsonInString反序列化构造PlayerStar对象,控制台输出结果如下(对象的toString()方法输出):

PlayerStar{name='乔丹', age=45, hobbies=[高尔夫球, 棒球], friends=null, salary=null}

@JsonCreator标注的构造方法里面下断点,也的确证明在java 对象反序列化构造的过程中使用的是该方法。

2.2.@JsonCreator注解加在工厂静态方法上

除了可以将@JsonCreator加在构造方法上,还可以使用静态工厂函数反序列化构造java对象。使用方法如下:

package org.zpli.springdemo.bean;import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;/*** created at 2021/6/3 3:14 下午** @author somnuszpli*/
public class PlayerStar {private String name;private Integer age;private String[] hobbies;               // 业余爱好,数组private List<String> friends;           // 朋友private Map<String, BigDecimal> salary; // 年收入 Map@JsonCreatorpublic static PlayerStar createPlayer(@JsonProperty("name") String name,@JsonProperty("age") Integer age,@JsonProperty("hobbies") String[] hobbies,@JsonProperty("friends") List<String> friends,@JsonProperty("salary") Map<String, BigDecimal> salary) {PlayerStar player = new PlayerStar();  //new 一个java对象player.name = name;    //赋值player.age = age;player.hobbies = hobbies;player.friends = friends;player.salary = salary;return player;}@Overridepublic String toString() {return "PlayerStar{" +"name='" + name + '\'' +", age=" + age +", hobbies=" + Arrays.toString(hobbies) +", friends=" + friends +", salary=" + salary +'}';}
}

使用@JsonCreator注解加在工厂静态方法上,可以达到一样的反序列化效果。

三、@ConstructorProperties注解

@ConstructorProperties注解的作用和@JsonCreator注解起到的作用是一致的,但是它只能加在构造方法上,作为反序列化函数。但是它的语法更简洁,使用起来也更加方便,不用@JsonProperty注解。又提供了灵活性,我们可以在构造方法反序列化过程中,针对该对象做更多的非规定操作。

package org.zpli.springdemo.bean;import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.beans.ConstructorProperties;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;/*** created at 2021/6/3 3:14 下午** @author somnuszpli*/
public class PlayerStar {private String name;private Integer age;private String[] hobbies;               // 业余爱好,数组private List<String> friends;           // 朋友private Map<String, BigDecimal> salary; // 年收入 Map@ConstructorProperties({"name", "age","hobbies", "friends","salary"})public PlayerStar(String name,Integer age,String[] hobbies,List<String> friends,Map<String, BigDecimal> salary) {this.name = name;this.age = age;this.hobbies = hobbies;this.friends = friends;this.salary = salary;}@Overridepublic String toString() {return "PlayerStar{" +"name='" + name + '\'' +", age=" + age +", hobbies=" + Arrays.toString(hobbies) +", friends=" + friends +", salary=" + salary +'}';}
}

使用@ConstructorProperties注解加在构造方法上,可以达到一样的反序列化效果。

这篇关于Jackson的序列化及反序列化【@JsonValue及@JsonCreator注解】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

Java利用@SneakyThrows注解提升异常处理效率详解

《Java利用@SneakyThrows注解提升异常处理效率详解》这篇文章将深度剖析@SneakyThrows的原理,用法,适用场景以及隐藏的陷阱,看看它如何让Java异常处理效率飙升50%,感兴趣的... 目录前言一、检查型异常的“诅咒”:为什么Java开发者讨厌它1.1 检查型异常的痛点1.2 为什么说

Java整合Protocol Buffers实现高效数据序列化实践

《Java整合ProtocolBuffers实现高效数据序列化实践》ProtocolBuffers是Google开发的一种语言中立、平台中立、可扩展的结构化数据序列化机制,类似于XML但更小、更快... 目录一、Protocol Buffers简介1.1 什么是Protocol Buffers1.2 Pro

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

Java中使用 @Builder 注解的简单示例

《Java中使用@Builder注解的简单示例》@Builder简化构建但存在复杂性,需配合其他注解,导致可变性、抽象类型处理难题,链式编程非最佳实践,适合长期对象,避免与@Data混用,改用@G... 目录一、案例二、不足之处大多数同学使用 @Builder 无非就是为了链式编程,然而 @Builder

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类

spring中的@MapperScan注解属性解析

《spring中的@MapperScan注解属性解析》@MapperScan是Spring集成MyBatis时自动扫描Mapper接口的注解,简化配置并支持多数据源,通过属性控制扫描路径和过滤条件,利... 目录一、核心功能与作用二、注解属性解析三、底层实现原理四、使用场景与最佳实践五、注意事项与常见问题六

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red