首页 > 其他分享 >序列化之@JsonComponent、@JsonInclude、@JsonSerialize、@JsonIgnore、JsonProperty区别与联系作用

序列化之@JsonComponent、@JsonInclude、@JsonSerialize、@JsonIgnore、JsonProperty区别与联系作用

时间:2024-01-20 22:02:22浏览次数:22  
标签:JsonProperty JsonComponent JsonSerialize jsonGenerator money class 序列化 public


前言:很多时候,例如前端需要字段user可能只是需要用到user中的userName属性,而后端传过去的却是一整个user对象,这样显然是不行的。那有没有一种技术,可以把后端传给前端的user类型的值改变为userName类型的值呢?@JsonComponent、@JsonInclude、@JsonSerialize可以在序列化的时候动手脚,可以自定义返回给前端的序列化的对象的值。完美解决这个问题。


本文概述

  • @JsonSerialize常见用法
  • 标注在类上面用法
  • 标注在属性、get方法上
  • @JsonProperty解析
  • @JsonIgnore解析
  • @JsonComponent解析
  • 注意点
  • 代码获取


@JsonSerialize常见用法

标注范围:类、属性、get方法
标注在类上面:指定类的序列化规则
标注在属性、get方法上面:指定属性的序列化规则

标注在类上面用法

这里使用了lombok插件省略了写法。伪代码模拟异常基类

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BaseException {
    private ErrorMsg errorMsg;
    private LocalDateTime date;
}

模拟自定义异常的这个场景,@JsonSerialize指定序列化规则,用我们自己定义的序列化器

@JsonSerialize(using = DivSerializer.class)
public class DivException extends BaseException {
    public DivException(ErrorMsg errorMsg, LocalDateTime date) {
        super(errorMsg, date);
    }
}

自定义序列化器,此处设置的值也就是前端能够接收到的值(没有设置的属性也就自然没有咯),干涉ErrorMsg = ErrorMsg.code

/**
 * @author 张子行
 * @class
 */
public class DivSerializer extends StdSerializer<DivException> {
    /**
     * @method 固定代码,原理搞不清
     */
    protected DivSerializer() {
        super(DivException.class);
    }
    /**
     * @method
     * @param DivException e:干涉前的对象
     * @param JsonGenerator jsonGenerator: json生成器,指定干涉后的json对象                    
     */
    @Override
    public void serialize(DivException e, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeObjectField("date", e.getDate());
        jsonGenerator.writeObjectField("ErrorMsg", e.getErrorMsg().getMsg());
        jsonGenerator.writeEndObject();
    }

测试代码注意加了@RestController返回值会经过json序列化

/**
* @author 张子行
* @class
*/
@RestController
public class GoodsController {
 @GetMapping("/testMoney")
 public money test() {
     money money = new money(100, LocalDateTime.now(), null, "zzh");
     return money;
 }

 @GetMapping("/testDivException")
 public DivException b() {
     DivException divException = new DivException(new ErrorMsg(100, "error"), LocalDateTime.now());
     return divException;
 }
}

不加@JsonSerialize效果

序列化之@JsonComponent、@JsonInclude、@JsonSerialize、@JsonIgnore、JsonProperty区别与联系作用_java


加了@JsonSerialize效果

序列化之@JsonComponent、@JsonInclude、@JsonSerialize、@JsonIgnore、JsonProperty区别与联系作用_归纳总结踩坑_02

标注在属性、get方法上

money类

/**
 * @author 张子行
 * @class
 */

/**
 * 类中有字段为null时不返回给前端
 */
@JsonInclude(value = JsonInclude.Include.NON_NULL)
@Data
@AllArgsConstructor
public class money {

    /**
     * 只能被序列化,序列化的key为macAmount
     */
    @JsonProperty(value = "macAmount", access = JsonProperty.Access.READ_ONLY)
    private int amount;
    /**
     * 使用自定义的序列化规则
     */
    @JsonSerialize(using = DateSerializer.class)
    private LocalDateTime date;
    /**
     * 为空时不会返回给前端
     */
    @JsonInclude(value = JsonInclude.Include.NON_EMPTY)
    private String unit;
    /**
     * 序列化不返回给前端的字段
     */
    @JsonIgnore
    private String name;
}

date序列化器

public class DateSerializer extends StdSerializer<LocalDateTime> {
    public DateSerializer() {
        super(LocalDateTime.class);
    }

    @Override
    public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeObject(localDateTime+"ggg");
    }
}

测试

/**
 * @author 张子行
 * @class
 */
@RestController
public class GoodsController {
    @GetMapping("/testMoney")
    public money test() {
        money money = new money(100, LocalDateTime.now(), null, "zzh");
        return money;
    }

    @GetMapping("/testDivException")
    public DivException b() {
        DivException divException = new DivException(new ErrorMsg(100, "error"), LocalDateTime.now());
        return divException;
    }
}

效果

name字段加了@JsonIgnore,所以不会被序列化

unit字段在@JsonInclude作用下,无论是空串还是null都不会被序列化

date字段在@JsonSerialize指定了序列化器下,输出的是时间+ggg

序列化之@JsonComponent、@JsonInclude、@JsonSerialize、@JsonIgnore、JsonProperty区别与联系作用_springboot项目_03

@JsonProperty解析

access = JsonProperty.Access.READ_ONLY,表示只能被序列化

/**
 * 只能被序列化
 */
 @JsonProperty(value = "macAmount", access = JsonProperty.Access.READ_ONLY)
 private int amount;

被序列化后的效果

{"macAmount": "value"}

@JsonIgnore解析

被@JsonIgnore标注的属性序列化的时候会被忽略。不序列此字段,效果图同上

@JsonComponent解析

为指定类设置序列化规则,无需其他任何额外配置,即可生效。当controller层中的返回值中包含money对象,那么就会被此序列化器作用

/**
 * @author 张子行
 * @class
 */
@JsonComponent
public class moneySerializer extends StdSerializer<money> {
    protected moneySerializer() {
        super(money.class);
    }

    /**
     * 序列化逻辑,只取出Money中的amount
     */
    @Override
    public void serialize(money money, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeStartObject();
        System.out.println(money);
        jsonGenerator.writeObjectField("amount", money.getAmount());
        jsonGenerator.writeObjectField("date", money.getDate());
        jsonGenerator.writeObjectField("unit", money.getUnit());
        jsonGenerator.writeObjectField("name", money.getName());
        jsonGenerator.writeEndObject();
    }
}

效果图,controller层同上。

unit为null是因为unit加了注解@JsonIgnore

date没有ggg尾缀请看下文注意点

序列化之@JsonComponent、@JsonInclude、@JsonSerialize、@JsonIgnore、JsonProperty区别与联系作用_java_04

注意点

此时下面代码会失效,被序列化器作用的类中的@JsonSerialize配置会失效

  • @JsonSerialize标注在类上且指定了序列化器a,序列化器a就不要加@JsonComponent注解。
  • 同理序列化器a为类b指定了序列化规则,类b就不要加@JsonSerialize注解指定序列化器
/**
     * 使用自定义的序列化规则
     */
    @JsonSerialize(using = DateSerializer.class)
    private LocalDateTime date;

代码获取

https://github.com/zhangzihang3/-workHarvestCode.git


标签:JsonProperty,JsonComponent,JsonSerialize,jsonGenerator,money,class,序列化,public
From: https://blog.51cto.com/u_16414043/9346326

相关文章

  • 为什么double会被序列化为NaN
    提问为什么double会被序列化为NaN回答世界上存在Double.NaN这个东西,他被序列化就会成为NaNexample//Seehttps://aka.ms/new-console-templateformoreinformationusingSystem.Globalization;usingNewtonsoft.Json;usingNewtonsoft.Json.Converters;Console.Writ......
  • Python pickle 二进制序列化和反序列化 - 数据持久化
    模块pickle实现了对一个Python对象结构的二进制序列化和反序列化。"pickling"是将Python对象及其所拥有的层次结构转化为一个字节流的过程,而"unpickling"是相反的操作,会将(来自一个binaryfile或者bytes-likeobject的)字节流转化回一个对象层次结构。pickling(和unp......
  • c# csharp 对象序列化
    对象序列化要将一个序列化对象存储起来,您可以使用C#中的序列化和反序列化功能。以下是一个示例代码,它演示了如何将一个序列化对象存储到文件中:usingSystem;usingSystem.IO;usingSystem.Runtime.Serialization.Formatters.Binary;namespaceMyNamespace{[Serializab......
  • 配置redisTemplate序列化,解决乱码与反序列化失败
    /***@projectName:MultiModuleDemo*@package:com.example.config*@className:RedisConfig*@description:TODO(配置RedisTemplate序列化)*@date:2023/12/1821:08*@version:1.0*/@ConfigurationpublicclassRedisConfig{@BeanpublicRedi......
  • C# 对象序列化 单元测试 .netframework
    对象序列化以及单元测试F:\song\netframework_serialize\netframework_serialize\Program.csusingnetframework_serialize.Animal;usingSystem;usingSystem.Collections.Generic;usingSystem.IO;usingSystem.Linq;usingSystem.Runtime.Serialization.Formatters.Bina......
  • SpringBoot集成Jackson实现JSON序列化
    一、前言Jackson是一个在Java中常用的JSON序列化和反序列化库,它具有操作简单、性能优秀、支持多种数据格式等特点,被广泛应用于各种服务端开发中。SpringMVC框架的默认json解析器也是Jackson。当前常见的json解析器还有Gson、fastjson等,jackson的优势是解析大的json文件处理速度快,运......
  • delphi JSON序列化(五)
    关于TJSONConverters的使用unitUnit1;interfaceusesWinapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls,Vcl.Buttons,Rest.JSON.Types,Rest.JsonReflect;t......
  • delphi JSON序列化(四)
    涉及的重要类REST.Json,REST.JsonReflect,REST.Json.Interceptors,REST.Json.Types单元中。一、TJson类最简单的一个类,提供了JSON->OBJECT和OBJECT->JSON几个方法,方法有TJsonOptions参数,如:   classfunctionObjectToJsonObject(AObject:TObject;AOptions:TJsonOpti......
  • netty: Marshalling序列化示例
    一、请求对象和响应对象,分别要实现Serializable接口packagecn.edu.tju;importjava.io.Serializable;publicclassUserRequestimplementsSerializable{privateStringusername;privateStringpassword;publicStringgetUsername(){returnus......
  • Java之序列化的详细解析
     3.序列化3.1概述Java提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反......