• JSON常用注解


    一、介绍

    1、前言

    在使用Java开发时,一定会接触到Json,而选择前后端开发都是使用Json进行数据传输,以及和数据库打交道的Bean类,相信你一定遇到过字段类型不同而导致的烦恼,而使用这些注解可以很方便进行字段转换、字段忽略等等

    这里我使用Spring自带的Jackson和阿里巴巴的FastJson作为记录

    2、依赖引入

    Jackson包默认依赖在spring-boot-starter-web下,如果需要使用FastJson包,则需要去除原有的Json依赖

    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
        <version>2.7.1version>
        <exclusions>
            <exclusion>
                <artifactId>spring-boot-starter-jsonartifactId>
                <groupId>org.springframework.bootgroupId>
            exclusion>
        exclusions>
    dependency>
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
        <version>2.0.1version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    二、Jackson常用注解

    1、@JsonIgnoreProperties

    类别:类注解

    作用:json序列化时将bean中的一些属性忽略掉,序列化和反序列化都受影响内部可以写多个属性,返回前端忽略该字段

    /**
    allowGetters,allowSetters一起用用来控制字段忽视是在序列化还是反序列化
    allowGetters=true:字段允许序列化,反序列的时候忽略该字段
    allowSetters=true:字段允许反序列化,序列化的时候忽略该字段
    ignoreUnknown=true:反序列化的时候忽视未知的字段,解决字段无法对应实体类会报错json解析异常
    */
    
    @JsonIgnoreProperties({"name"},{"age"})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、@JsonIgnore

    类别:属性或方法上的注解(最好是属性上)
    作用:用来完全忽略被注解的字段和方法对应的属性,序列化和反序列化都受影响,返回前端忽略该字段

    @JsonIgnore
    private int age;
    
    • 1
    • 2

    3、@JsonIgnoreType

    类别:类注解
    作用:类在序列化和反序列化的时候被忽略,只有在该类作为其他类的属性时才会被忽略,直接序列化、反序列化该类是正常的,主要用来对一些数据敏感的对象进行忽略,比如用户的凭据

    4、@JsonFormat

    类别:用于属性或方法上(最好是属性上)
    作用:在需要查询出来的时间的数据库字段对应的实体类的属性上添加,返回的时候会自动格式化,可以在属性对应的get方法上,两种方式没有区别

    @JsonFormat(pattern="yyyy-MM-dd",timezone = "GMT+8")
    private Date createTime;
    
    // 如果想把前端日期字符串转换成Date格式 @DateTimeFormat(pattern="yyyy-MM-dd")
    
    • 1
    • 2
    • 3
    • 4

    5、@JsonProperty

    类别:用于属性

    作用:指定某个属性和json映射的名称

    • 前端传过来的参数,想用其他属性名接收,可以在属性上加此注解

    • 后端返回给前端数据时,前端要求指定key,可在属性上加此注解,就会以注解中的value返回

    public class User {
    
        // 这样前端接受的字段为user_name
        @JsonProperty("user_name")
        private String userName;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6、@Transient

    类别:用于属性或方法上(最好是属性上)

    作用:属性不与数据库表的字段映射—该字段在数据库中不存在,而需要使用。实体类中使用了@Table注解后,想要添加表中不存在的字段,就要使用@Transient这个注解;同时还有transient关键字标记的成员变量不参与序列化过程。

    7、@JsonSerialize

    类别:用于属性或getter方法,在序列化时嵌入自定义代码

    作用:需要使用 using 属性指定处理参数的类,该类需要继承 JsonSerializer 类,并重写 serialize()。 若使用了 Lombok 需要自己定义相应的 get 方法。

    @JsonSerialize(using = CustomDateSerialize.class)
    public Date getDate() {
        return date;
    }
    
    public class CustomDateSerialize extends JsonSerializer<Date> {
    
        // 定义日期格式
        private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    
        @Override
        public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            jsonGenerator.writeString(simpleDateFormat.format(date));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    8、@JsonDeserialize

    类别:用于属性或者setter方法上,用于在反序列化时可以嵌入我们自定义的代码,类似于上面的@JsonSerialize

    作用:需要使用 using 属性指定处理参数的类,该类需要继承 JsonSerializer 类,并重写 serialize()。 若使用了 Lombok 需要自己定义相应的 get 方法。

    //在前端性别显示"男 / 女";数据库中存储的是"1 / 0",对应的 Pojo 也是使用的 Integer 类型
    @Data
    public class Person implements Serializable {
        private static final long serialVersionUID = 4346092911489022673L;
        
        /**
         * 1 男,0 女
         */
        private Integer gender;
    
        @JsonDeserialize(using = GenderJsonDeserializer.class)
        public void setGender(Integer gender) {
            this.gender = gender;
        }
    
        @JsonSerialize(using = GenderJsonSerializer.class)
        public Integer getGender() {
            return gender;
        }
    }
    
    // JsonDeserializer 作用是:处理参数,按照规则封装到指定的属性中,通过 jsonParser.getText() 获取参数
    public class GenderJsonDeserializer extends JsonDeserializer {
        @Override
        public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            if (ObjectUtils.isEmpty(jsonParser)) {
                return null;
            }
            int gender = 0;
            switch (jsonParser.getText()) { // 通过getText获取参数
                case "男":
                    gender = 1;
                    break;
                case "女":
                    break;
                default:
                    throw new RuntimeException("传入的性别为非法字符");
            }
    
            return gender;
        }
    }
    
    //JsonSerializer 作用是:处理属性,按照规则封装到指定的参数中,通过value获取属性通过 jsonGenerator.writeXxx() 写出参数
    public class GenderJsonSerializer extends JsonSerializer {
        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            if (o.equals(1)) {
                jsonGenerator.writeString("男"); // 写出参数
            } else if (o.equals(0)) {
                jsonGenerator.writeString("女"); // 写出参数
            }
        }
    }
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    9、序列化其他相关注解

    9.1 @JsonPropertyOrder

    在将 java pojo 对象序列化成为 json 字符串时,使用 @JsonPropertyOrder 可以指定属性在 json 字符串中的顺序

    9.2 @JsonInclude

    在将 java pojo 对象序列化成为 json 字符串时,使用 @JsonInclude 注解可以控制在哪些情况下才将被注解的属性转换成 json

    • ALWAYS :默认策略,任何情况下都序列化该字段

    • NON_NULL:注解的字段为null不序列化

    • NON_ABSENT:注解的字段为null的时候不序列化

    • NON_EMPTY :注解的字段为null或为空不序列化

    • NON_DEFAULT:字段是默认值的话就不序列化

    • CUSTOM:自定义排除序列化规则,过滤器对象的 equals() 方法被调用并带有要序列化的值; 如果返回真值则排除(即过滤掉)

    • USE_DEFAULTS:伪值用于指示更高级别的默认值是有意义的,以避免覆盖包含值。 例如,如果返回一个属性,这将使用包含属性的类的默认值,如果有的话; 如果没有为此定义,则全局序列化包含详细信息。

    9.3 @JsonGetter、@JsonSetter注解

    @JsonGetter@JsonSetter注解只能用在getter和setter方法上,用来反序列化为指定字段名和序列化时为指定字段名,可以替换上面的@JsonProperty也可以被替换;

    public class People {
    
        private String username;
    
        @JsonGetter("USERNAME")
        public String getUsername() {
            return username;
        }
    
        @JsonSetter("USERNAME")
        public void setUsername(String username) {
            this.username = username;
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    9.4 @JsonAnySetter和@JsonAnyGetter注解

    • @JsonAnySetter注解是在反序列化时实体对象不存在对应的属性时加上该 注解,不存在的属性都会放到Map中去

    • @JsonAnyGetter注解在序列化时Map加上该属性可以将map中的属性序列化为指定字符串

    public class People {
    
        private String username;
        private Map<String, String> properties;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
        @JsonAnyGetter
        public Map<String, String> getProperties() {
            return properties;
        }
        @JsonAnySetter
        public void setProperties(Map<String, String> properties) {
            this.properties = properties;
        }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    三、FastJson常用注解

    文档:https://www.w3cschool.cn/fastjson/fastjson-intro.html
    官方文档:https://github.com/alibaba/fastjson/wiki/Quick-Start-CN

    1、介绍

    FastJson提供了4种注解,分别是@JSONType@JSONCreator@JSONField@JSONPOJOBuilder

    2、@JSONField

    // 若属性是私有的,必须有set*方法。否则无法反序列化。
    public @interface JSONField {
      // 配置序列化和反序列化的顺序,1.1.42版本之后才⽀持
      int ordinal() default 0;
      // 指定字段的名称
      String name() default "";
      // 指定字段的格式,对⽇期格式有⽤
      String format() default "";
      // 是否序列化
      boolean serialize() default true;
      // 是否反序列化
      boolean deserialize() default true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • @JSONField(ordinal =0) 序列化字段的顺序,默认是0

    • @JSONField(name = “”) 用于解决属性名和key不一致的情况,当前端传过来的字段名不一样的时候,我们可以在字段名上加上这个注解

    • @JSONField(format = “yyyy-MM-dd HH:mm:ss”) , 用在Date属性上,自动格式化日期

    • @JSONField(serialize = false) 是否要把这个字段序列化成JSON字符串,默认是true

    • @JSONField(deserialize = false) 字段是否需要进行反序列化,默认是true

    3、@JSONType

    放在实体类上就会只装配列举的字段或者排除列举的成员变量

    //不序列化这两个
    @JSONType(ignores = {"id", "sex"})  
    public class Pojo2
    
    //序列化只序列化这两个属性
    @JSONType(includes = {"name", "sex"})  
    public class Pojo1 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    https://juejin.cn/post/7115219049931341854

  • 相关阅读:
    Linux学习之远程拷贝数据命令
    推理还是背诵?通过反事实任务探索语言模型的能力和局限性
    Vue原生写全选反选框
    Android如何管理多进程
    Linux 查看CPU架构及内核版本
    leetcode刷题详解——粉刷房子
    学习记忆——宫殿篇——记忆宫殿——记忆桩——火车+外院+客厅+卧室
    大数据毕业设计选题推荐(二)
    MySQL提示sql_mode=only_full_group_by解决办法
    十、为影院添加影片及座位安排《仿淘票票系统前后端完全制作(除支付外)》
  • 原文地址:https://blog.csdn.net/lemon_TT/article/details/126063344