Jackson中@JsonIgnore,@JsonValue,@JsonCreator注解作用

@JsonIgnore,@JsonValue,@JsonCreator

通过具体的代码测试,来说明三者的作用。

两个名词:

序列化:实体转为Json格式,比如Controller层,返回给前端。

反序列化:Json格式数据转为实体,比如前端传递Json数据给Controller。

@JsonIgnore

注解在哪个字段上,则这个字段不会参与序列化和反序列化。

	// @JsonIgnore
	@Test
	public void test01() throws Exception {

		Student student = new Student();
		student.setId(1L);
		student.setEmail("xiaolaoben@233.com");
		student.setTelphone("12312311122");
		student.setUserName("小老犇");

		// 不加注解,效果
		String json = JacksonUtils.obj2json(student);
		System.out.println("不加注解,效果:all you(都有)" + json); // {"id":1,"userName":"小老犇","telphone":"12312311122","email":"xiaolaoben@233.com"}

//		// 加注解,序列化时,@JsonIgnore效果
		String pojotojson = JacksonUtils.obj2json(student);
		System.out.println("序列化时,效果:忽略电话字段值" + pojotojson); // {"id":1,"userName":"小老犇","email":"xiaolaoben@233.com"}

//		// 加注解,反序列化时,@JsonIgnore效果
		String jsonToPojo = "{\"id\":1,\"userName\":\"小老犇\",\"telphone\":\"12312311122\",\"email\":\"xiaolaoben@233.com\"}";
		Student pojo = JacksonUtils.json2pojo(jsonToPojo, Student.class);
		System.out.println("反序列化时,效果:忽略电话字段值" + pojo); // Student(id=1, userName=小老犇, telphone=null, email=xiaolaoben@233.com)

	}

@JsonValue

序列化时,指定将枚举字段,反序列化为什么值。

常用于枚举类中,注解在getCode()方法上,返回给前端code,数字。

	@Test
	public void test02() throws Exception {

		// 不使用注解
//		String no = JacksonUtils.obj2json(StudentEnum.FEMALE);
//		System.out.println("不使用注解,效果:同英文名" + no); // "FEMALE"

		// 使用注解
		String have = JacksonUtils.obj2json(StudentEnum.FEMALE);
		System.out.println("使用注解,效果:对应字段的值" + have);// 1002

	}

	// 开发过程中,Controller层序列化实体类,即后端to前端的过程。
	@Test
	public void test03() throws Exception {

		Student student = new Student();
		student.setId(1L);
		student.setEmail("xiaolaoben@233.com");
		student.setTelphone("12312311122");
		student.setUserName("小老犇");
		student.setSex(StudentEnum.FEMALE);

		// 不使用注解
		String no = JacksonUtils.obj2json(student);
		System.out.println("不使用注解,效果:同英文名" + no); // {"id":1,"userName":"小老犇","telphone":"12312311122","email":"xiaolaoben@233.com","sex":"FEMALE"}

		// 使用注解
		String have = JacksonUtils.obj2json(student);
		System.out.println("使用注解,效果:对应字段的值" + have);// {"id":1,"userName":"小老犇","telphone":"12312311122","email":"xiaolaoben@233.com","sex":1002}

	}

@JsonCreator

用于反序列化时,指定构造方法可以在构造方法内部,进行业务处理,常用于枚举类中。

比如:

我们自定义的枚举类,往往是有自己的code,比如FEMALE(1002, “女性”)中的1002,相对应的前端传过来的,和数据库中存的也都是1002。

如果我们不使用JsonCreator,那么我们的1002,就会没有作用,前端传过来的数据,直接报错,反序列化失败。

不使用注解

	@Test
	public void test04() throws Exception {
	
		String no = "{\"id\":1,\"userName\":\"小老犇\",\"telphone\":\"12312311122\",\"email\":\"xiaolaoben@233.com\",\"sex\":0}";
		Student pojo = JacksonUtils.json2pojo(no, Student.class);
		System.out.println(pojo);
	}

此时,枚举中自定义的code无效,使用枚举类内置下标ordinal,从0开始排序,可以反序列化成功。

若传入code不在枚举类中默认code,则报错:

 com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.huwei.system.StudentEnum` from number -1: index value outside legal index range [0..2] at [Source: (String)"{"id":1,"userName":"小老犇","telphone":"12312311122","email":"xiaolaoben@233.com","sex":-1}"; line: 1, column: 86] (through reference chain: com.huwei.system.Student["sex"])

使用注解

@Test
	public void test05() throws Exception {

		String have = "{\"id\":1,\"userName\":\"小老犇\",\"telphone\":\"12312311122\",\"email\":\"xiaolaoben@233.com\",\"sex\":1002}";
		Student student = JacksonUtils.json2pojo(have, Student.class);
		System.out.println(student);

	}

Jackson在反序列化的时候,会使用实体的默认无参构造函数来实例化一个对象,然后使用对象的setter方法来初始化属性值。

现在我们在反序列化Student类,查看控制台日志(如图):
在这里插入图片描述
可以看出,现在@JsonCreator注解生效,反序列化Student类时,其中枚举字段的构造,走的是我们自定义的构造方法,通过处理,返回我们的枚举字段。此时,自定义的code生效。

测试代码:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

import java.util.stream.Stream;

public enum StudentEnum {

	UNKNOWN(0, "未知"),

	MALE(1001, "男性"),

	FEMALE(1002, "女性"),

	NOMALE(1003, "妖怪");

	private String desc;

	private int code;

	StudentEnum(int code, String desc) {
		this.code = code;
		this.desc = desc;
	}

	public String getDesc() {
		return this.desc;
	}

	@JsonValue
	public Integer getCode() {
		return this.code;
	}

	@JsonCreator
	public static StudentEnum forValue(Integer value) {
		System.out.println("我在走枚举类型的自定义构造方法!");
		StudentEnum[] values = StudentEnum.values();
		return Stream.of(values).filter(it -> it.getCode().equals(value)).findAny().orElse(UNKNOWN);
	}

}
import io.swagger.annotations.ApiModelProperty;

/**
 * @author jjsai
 * @date 2021/7/11 19:05
 **/
public class Student {

	@ApiModelProperty(value = "主键")
	private Long id;

	@ApiModelProperty(value = "用户名")
	private String userName;

	@ApiModelProperty(value = "手机号")
	private String telphone;

	@ApiModelProperty(value = "邮箱")
	private String email;

	@ApiModelProperty(value = "性别")
	private StudentEnum sex;

	public Student() {
		System.out.println("我在走student的空参构造");
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getTelphone() {
		return telphone;
	}

	public void setTelphone(String telphone) {
		this.telphone = telphone;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public StudentEnum getSex() {
		return sex;
	}

	public void setSex(StudentEnum sex) {
		System.out.println("我在走Student类中的枚举字段sex的set方法");
		this.sex = sex;
	}

	@Override
	public String toString() {
		return "Student{" +
				"id=" + id +
				", userName='" + userName + '\'' +
				", telphone='" + telphone + '\'' +
				", email='" + email + '\'' +
				", sex=" + sex +
				'}';
	}

}
import org.junit.jupiter.api.Test;

/**
 * @author jjsai
 * @date 2021/7/11 19:01
 **/
public class JacksonTest {


	// @JsonIgnore
	@Test
	public void test01() throws Exception {
		Student student = new Student();
		student.setId(1L);
		student.setEmail("xiaolaoben@233.com");
		student.setTelphone("12312311122");
		student.setUserName("小老犇");

		// 不加注解,效果
		String json = JacksonUtils.obj2json(student);
		System.out.println("不加注解,效果:all you(都有)" + json); // {"id":1,"userName":"小老犇","telphone":"12312311122","email":"xiaolaoben@233.com"}

//		// 加注解,序列化时,@JsonIgnore效果
		String pojotojson = JacksonUtils.obj2json(student);
		System.out.println("序列化时,效果:忽略电话字段值" + pojotojson); // {"id":1,"userName":"小老犇","email":"xiaolaoben@233.com"}

//		// 加注解,反序列化时,@JsonIgnore效果
		String jsonToPojo = "{\"id\":1,\"userName\":\"小老犇\",\"telphone\":\"12312311122\",\"email\":\"xiaolaoben@233.com\"}";
		Student pojo = JacksonUtils.json2pojo(jsonToPojo, Student.class);
		System.out.println("反序列化时,效果:忽略电话字段值" + pojo); // Student(id=1, userName=小老犇, telphone=null, email=xiaolaoben@233.com)

	}

	// JsonValue
	@Test
	public void test02() throws Exception {

		// 不使用注解
		String no = JacksonUtils.obj2json(StudentEnum.FEMALE);
		System.out.println("不使用注解,效果:同英文名" + no); // "FEMALE"

		// 加上注解效果
		String have = JacksonUtils.obj2json(StudentEnum.FEMALE);
		System.out.println("使用注解,效果:对应字段的值" + have);// 1002

	}


	// 序列化实体类,即后端to前端的过程。
	@Test
	public void test03() throws Exception {
		Student student = new Student();
		student.setId(1L);
		student.setEmail("xiaolaoben@233.com");
		student.setTelphone("12312311122");
		student.setUserName("小老犇");
		student.setSex(StudentEnum.FEMALE);

		// 不使用注解
		String no = JacksonUtils.obj2json(student);
		System.out.println("不使用注解,效果:同英文名" + no); // {"id":1,"userName":"小老犇","telphone":"12312311122","email":"xiaolaoben@233.com","sex":"FEMALE"}

		// 使用注解
		String have = JacksonUtils.obj2json(student);
		System.out.println("使用注解,效果:对应字段的值" + have);// {"id":1,"userName":"小老犇","telphone":"12312311122","email":"xiaolaoben@233.com","sex":1002}

	}

	// @JsonCreator  不使用注解
	@Test
	public void test04() throws Exception {
		String no = "{\"id\":1,\"userName\":\"小老犇\",\"telphone\":\"12312311122\",\"email\":\"xiaolaoben@233.com\",\"sex\":0}";
		Student pojo = JacksonUtils.json2pojo(no, Student.class);
		System.out.println(pojo);
	}

	// @JsonCreator  使用注解
	@Test
	public void test05() throws Exception {
		String have = "{\"id\":1,\"userName\":\"小老犇\",\"telphone\":\"12312311122\",\"email\":\"xiaolaoben@233.com\",\"sex\":1002}";
		Student student = JacksonUtils.json2pojo(have, Student.class);
		System.out.println(student);
	}

}

JacksonUtils工具类网上随便找一个就好。

比如:

https://www.cnblogs.com/f-society/p/12852563.html

完事!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值