Jackson annotation usage analysis


Jackson Common Annotations

1. Summary of common annotations

annotation Scope of action main attribute describe
JsonProperty fields, methods value: specify the json field name
access: specify permissions
required:
index:
defaultValue:
Specify the serialization and deserialization field Json field name
JsonPropertyOrder kind value: an array of field order, with unconfigured fields in the back Field sorting when specifying serialization
JsonIgnore Fields, get and set methods value: the default is true, false is not ignored Specify serialization and deserialization to ignore fields
JsonIgnoreType kind value: the default is true, false is not ignored Specify serialization and deserialization to ignore the type (when the class is used as an attribute of another class, all fields of the class are ignored)
JsonIgnoreProperties kind value: array, specify the fields to ignore
ignoreUnknown: default false, ignore unknown fields
allowGetters: default false, allow to get the value from the get method
allowSetters: default false, allow the set method to set the value
Specify serialization, deserialization ignore field collection
JsonGetter getter method value: specify the json field name Specify the Json field name when serializing, used in the get method, with a higher priority than @JsonProperty
JsonSetter setter method value: specify the json field name Specify the Json field name when deserializing, used in the set method, with a higher priority than @JsonProperty
JsonInclude class, field, method value: serialization rule Specify serialization rules
JsonRootName kind value: root node name Specify the root node name for serialization and deserialization
JsonFormat fields, methods, parameters pattern: time format
timezone: time zone
Set the time formatting format when serializing
JsonAnyGetter method enabled: whether to enable, the default is true Acting on the method, you can flexibly serialize attributes of type Map into JSON strings as standard attributes. The method return value must be a Map. Expand the key/value pairs in the Map to the same level of the current class during serialization
JsonAnySetter method, field enabled: whether to enable, the default is true Generally acting on methods, the input parameters of the method must have key and value. When deserializing, the attribute in Json that does not match the class will call the method of the specified JsonAnySetter annotation, passing in the attribute and attribute value
JsonNaming kind value: attribute naming strategy Specifies the attribute naming strategy for serialization and deserialization.
JsonCreator Construction method mode: specify the mode Specifies the construction method used for deserialization, which needs to be used in conjunction with the JsonProperty annotation, such as:
@JsonCreator
public User(@JsonProperty(“id”)String id) {…}
JsonAutoDetect kind Specify the visibility of fields and methods
JsonUnwrapped fields, methods, parameters enabled: Whether it is enabled, the default is true
prefix: attribute name prefix
suffix: attribute name suffix
Move its properties up one level to expand
JacksonInject fields, methods, parameters value: field identifier
userInput: whether the Json attribute value overrides the default value, the default is TRUE
When specifying deserialization, whether the Json field value overrides the default value of the entity class attribute
JsonAlias fields, methods, parameters value: alias collection When deserializing, specify multiple Json field names that can match entity class attributes
JsonValue fields, methods value: whether to enable A class can only use one. When annotated with JsonValue, only the value of this field will be returned during serialization, not all attribute key-value pairs of this class.
A class can only have at most one JsonValue annotation, otherwise an exception will be thrown; but multiple classes can have one JsonValue annotation at the same time, and the serialization is normal
JsonMerge fields, methods, parameters value: whether to enable merging When deserializing, merge the elements of the Json collection field with the default elements of the corresponding attributes of the entity class
JsonRawValue fields, methods value: whether to enable When serializing, the attribute value is output as it is, and the attribute value will not include escape and quotation marks (that is, the attribute value will automatically escape and remove redundant quotation marks)
JsonEnumDefaultValue field - 反序列化时,当枚举字段遇到未知的枚举值,使用JsonEnumDefaultValue注解指定的默认枚举值
需要注意:该注解需要开启DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE才生效
JsonFilter 类、字段、方法、参数 value:指定过滤器ID 序列化时,过滤掉不需要的属性
JsonSerialize 类、字段、方法、参数 using:非null时使用的序列化器
nullsUsing:null时使用的序列化器
序列化时,指定字段序列化使用的序列化器
JsonDeserialize 类、字段、方法、参数 using:非null时使用的序列化器
nullsUsing:null时使用的序列化器
反序列化时,指定字段反序列化使用的反序列化器
JacksonAnnotation 注解类 - Jackson注解的元注解,注解上使用JacksonAnnotation表示该注解时Jackson相关注解
JacksonAnnotationsInside 注解类 - Jackson注解的元注解,可以将其他注解封装成一个组合注解,通常用于Jackson自定义注解
JsonView
JsonAppend attrs:序列化时要包括的一组虚拟属性
props:序列化时要包括的一组通用虚拟属性
prepend:虚拟属性附加在常规属性前面还是右面,默认false(后面)
用于在序列化对象时向对象添加虚拟属性
JsonIdentityInfo 类、字段、方法、参数 property:对象标识的属性名
generator:对象标识的生成器
用于处理对象的循环引用(序列化、反序列化),在第一次遇到时序列化为完整的对象,之后再遇到同一个对象,都以对象的标识符代替。能解决一对一、一对多、多对多的循环引用
JsonIdentityReference 类、字段、方法、参数 alwaysAsId:是否总是序列化为对象标识 可以强制序列化为对象标识,而不是将第一个实例序列化为完整的 POJO,第二次才序列化为对象标识。必须与@JsonIdentityInfo 一起使用
JsonBackReference 字段、方法 @JsonBackReference标注的属性在序列化(serialization,即将对象转换为json数据)时,会被忽略(即结果中的json数据不包含该属性的内容)。
在序列化时,@JsonBackReference的作用相当于@JsonIgnore
JsonManagedReference 字段、方法 如果有@JsonManagedReference,则会自动注入@JsonBackReference标注的属性
JsonPOJOBuilder buildMethodName: 无参数方法的名称,用于在将JSON字段绑定到bean的属性之后实例化预期的bean。默认名称为“build”
withPrefix: 用于自动检测JSON和bean属性之间的匹配的名称前缀。默认前缀是 with
用于配置构建器类,以自定义JSON文档的反序列化,以便在命名约定与默认约定不同的情况下恢复POJO。

2. 注解使用分析

@JsonInclude

序列化规则:

  • JsonInclude.Include. ALWAYS:默认,全部序列化

  • JsonInclude.Include.NON_NULL:非null字段序列化

  • JsonInclude.Include.NON_EMPTY:非null、非空字符串、非空数组、非空引用Optional、非空引用AtomicReference的字段序列化

  • JsonInclude.Include.NON_DEFAULT:值有变动的字段序列化

    何为有变动的字段:

    • 默认值:调用实体的无参构造函数创建一个实例,调用属性对应的get方法,将其返回值作为属性的默认值
    • 值有变动:属性的值与默认值不相同时,视为值有变动
  • JsonInclude.Include.NON_ABSENT:

  • JsonInclude.Include.CUSTOM:

@JsonAnyGetter

@JsonAnyGetter注解 可以灵活地把类型为Map的属性作为标准属性序列化到JSON字符串中,有如下特点:

  • 方法为非静态方法,并且方法不带任何参数,方法名没有特殊约定(随意定义方法名称)
  • 方法返回值必须是Map类型
  • 在一个实体类中只能用在一个方法上
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;

    private Map<String, String> other;

    @JsonAnyGetter
    public Map<String, String> findOther() {
    
    
        return other;
    }

    public void addOther( String key,  String value) {
    
    
        if (other == null) {
    
    
            other = new HashMap<>();
        }
        other.put(key, value);
    }

    public String getId() {
    
    
        return id;
    }

    public User setId(String id) {
    
    
        this.id = id;
        return this;
    }

    public String getUserName() {
    
    
        return userName;
    }

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

    public String getPassWord() {
    
    
        return passWord;
    }

    public User setPassWord(String passWord) {
    
    
        this.passWord = passWord;
        return this;
    }
}
    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.addOther("email", "[email protected]");
        user.addOther("email1", "[email protected]");
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出

{
    
    
  "id" : "999",
  "userName" : "小五",
  "passWord" : "888888",
  "email1" : "[email protected]",
  "email" : "[email protected]"
}

@JsonAnySetter

public class User {
    
    
    private String id;
    private String userName;
    private String passWord;

    private Map<String, String> other;

    public Map<String, String> findOther() {
    
    
        return other;
    }

    @JsonAnySetter
    public void addOther( String key,  String value) {
    
    
        if (other == null) {
    
    
            other = new HashMap<>();
        }
        other.put(key, value);
    }

    public String getId() {
    
    
        return id;
    }

    public User setId(String id) {
    
    
        this.id = id;
        return this;
    }

    public String getUserName() {
    
    
        return userName;
    }

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

    public String getPassWord() {
    
    
        return passWord;
    }

    public User setPassWord(String passWord) {
    
    
        this.passWord = passWord;
        return this;
    }
}
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"id\":\"999\",\"userName\":\"小五\",\"passWord\":\"888888\",\"email\":\"[email protected]\",\"nickName\":null,\"sex\":\"女\",\"createTime\":null}";
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }

user对象
在这里插入图片描述

@JsonNaming

PropertyNamingStrategy:属性命名策略,具体策略有:

策略名称 描述 举例
PropertyNamingStrategy 小驼峰(默认策略) userName
SnakeCaseStrategy 小写+下划线 user_name
UpperCamelCaseStrategy 大驼峰 UserName
LowerCaseStrategy 小写 username
KebabCaseStrategy 小写+连字符 user-name
LowerDotCaseStrategy 小写+点号 user.name

匹配的优先级:JsonProperty注解指定的字段名称优先级高于JsonNaming注解指定的属性命名策略对应的字段名称

@JsonAutoDetect

默认情况下,Jackson 只使用 public 的字段进行序列化和反序列化。没有 public 字段时,会使用 public 的 getters/setters。通过@JsonAutoDetect可以指定字段、方法的可见性规则。

注解的属性:

  • getterVisibility:get方法的可见性,默认JsonAutoDetect.Visibility.DEFAULT
  • isGetterVisibility:is方法的可见性,默认JsonAutoDetect.Visibility.DEFAULT
  • setterVisibility:set方法的可见性,默认JsonAutoDetect.Visibility.DEFAULT
  • creatorVisibility:构造方法(非无参构造方法)的可见性,默认JsonAutoDetect.Visibility.DEFAULT
  • fieldVisibility:字段的可见性,默认JsonAutoDetect.Visibility.DEFAULT

JsonAutoDetect.Visibility:可见性枚举类

  • ANY:都可见
  • NON_PRIVATE:除private修饰的,其它都可见
  • PROTECTED_AND_PUBLIC:protected和public修饰的可见,其它不可见
  • PUBLIC_ONLY:只有public修饰的可见,其它都不可见
  • NONE:都不可见
  • DEFAULT:

java可见性修饰符:public、protected、默认、private

@JacksonInject

useInput属性,值为OptBoolean枚举类型

  • OptBoolean.TRUE:属性值覆盖默认值。
  • OptBoolean.FALSE:属性值不覆盖默认值,相当于定死了这个字段的值为默认值。
  • OptBoolean.DEFAULT:默认值,等同于OptBoolean.TRUE。该值主要是为了向后兼容(2.8 和更早版本始终允许绑定输入值)。
@Data
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    @JacksonInject(value = "nickName")
    private String nickName;
    private Date createTime;
}
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"id\":\"999\",\"userName\":\"小五\",\"passWord\":\"888888\",\"email\":null,\"createTime\":null}";
        ObjectMapper objectMapper = new ObjectMapper();
        InjectableValues.Std injectableValues = new InjectableValues.Std();
        injectableValues.addValue("nickName","小明");
        objectMapper.setInjectableValues(injectableValues);
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }
    // 输出:User(id=999, userName=小五, passWord=888888, email=null, nickName=小明, createTime=null)
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"id\":\"999\",\"userName\":\"小五\",\"passWord\":\"888888\",\"email\":null,\"nickName\":null,\"createTime\":null}";
        ObjectMapper objectMapper = new ObjectMapper();
        InjectableValues.Std injectableValues = new InjectableValues.Std();
        injectableValues.addValue("nickName","小明");
        objectMapper.setInjectableValues(injectableValues);
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }
    // 输出:User(id=999, userName=小五, passWord=888888, email=null, nickName=null, createTime=null)

@JsonAlias

@Data
public class User {
    
    
    private String id;
    @JsonAlias({
    
    "userName1", "userName2" })
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
}
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"id\":\"999\",\"userName\":\"小五\",\"passWord\":\"888888\",\"email\":null,\"nickName\":null,\"createTime\":null}";
        ObjectMapper objectMapper = new ObjectMapper();
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }
    // 输出:User(id=999, userName=小五, passWord=888888, email=null, nickName=null, createTime=null)
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"id\":\"999\",\"userName1\":\"小五\",\"passWord\":\"888888\",\"email\":null,\"nickName\":null,\"createTime\":null}";
        ObjectMapper objectMapper = new ObjectMapper();
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }
    // 输出:User(id=999, userName=小五, passWord=888888, email=null, nickName=null, createTime=null)
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"id\":\"999\",\"userName2\":\"小五\",\"passWord\":\"888888\",\"email\":null,\"nickName\":null,\"createTime\":null}";
        ObjectMapper objectMapper = new ObjectMapper();
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }
    // 输出:User(id=999, userName=小五, passWord=888888, email=null, nickName=null, createTime=null)

@JsonValue

JsonValue注解一般用在属性字段或者get方法上。当加上@JsonValue注解时,序列化时只返回这一个字段的值,而不是这个类的所有属性键值对。
需要注意:

  • 一个类最多只能有一个JsonValue注解,否则会抛出异常
  • 多个类中可同时有一个JsonValue注解,序列化正常
    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setCardInfo(new CardInfo("1", "123445"));
        ObjectMapper objectMapper = new ObjectMapper();
        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

例1:

@Data
public class User {
    
    
    private String id;
    private String userName;
    @JsonValue
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    private CardInfo cardInfo;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class CardInfo {
    
    

    private String cardType;
    private String cardNum;
}

输出

"888888"

例2:

@Data
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    private CardInfo cardInfo;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class CardInfo {
    
    

    @JsonValue
    private String cardType;
    private String cardNum;
}

输出

{
    
    "id":"999","userName":"小五","passWord":"888888","email":null,"nickName":null,"createTime":null,"cardInfo":"1"}

例3:

@Data
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    private CardInfo cardInfo;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class CardInfo {
    
    

    @JsonValue
    private String cardType;
    @JsonValue
    private String cardNum;
}

输出

com.fasterxml.jackson.databind.JsonMappingException: Problem with definition of [AnnotedClass com.joker.test.json.CardInfo]: Multiple 'as-value' properties defined ([field com.joker.test.json.CardInfo#cardType] vs [field com.joker.test.json.CardInfo#cardNum]) (through reference chain: com.joker.test.json.User["cardInfo"])
	at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:292)
	at com.fasterxml.jackson.databind.SerializerProvider.reportMappingProblem(SerializerProvider.java:1223)
	at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1341)
	at com.fasterxml.jackson.databind.SerializerProvider.findPrimaryPropertySerializer(SerializerProvider.java:668)
	at com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap.findAndAddPrimarySerializer(PropertySerializerMap.java:64)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter._findAndAddDynamic(BeanPropertyWriter.java:897)
	at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:705)
	at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:722)
	at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:166)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
	at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
	at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:4094)
	at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3404)
	at com.joker.test.json.JacksonTest.object2JsonStr(JacksonTest.java:152)
	at com.joker.test.json.JacksonTest.main(JacksonTest.java:267)

一个类出现多个JsonValue注解,序列化会抛出异常。

例4:

@Data
public class User {
    
    

    private String id;
    private String userName;
    @JsonValue
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    private CardInfo cardInfo;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class CardInfo {
    
    

    @JsonValue
    private String cardType;
    private String cardNum;
}

输出

"888888"

多个类中同时有一个JsonValue注解,序列化正常。

@JsonMerge

反序列化时,将Json集合字段的元素与实体类对应属性默认元素合并。

@Data
public class User {
    
    

    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    private CardInfo cardInfo;
    @JsonMerge
    private List<String> list = new ArrayList<>(Collections.singletonList("篮球"));
}
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"id\":\"999\",\"userName\":\"小五\",\"passWord\":\"888888\",\"email\":null,\"nickName\":null,\"createTime\":null,\"cardInfo\":{\"cardType\":\"1\",\"cardNum\":\"123445\"},\"list\":[\"排球\",\"足球\",\"乒乓球\"]}";
        ObjectMapper objectMapper = new ObjectMapper();
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }

输出

User(id=999, userName=小五, passWord=888888, email=null, nickName=null, createTime=null, cardInfo=CardInfo(cardType=1, cardNum=123445), list=[篮球, 排球, 足球, 乒乓球])

list集合将默认元素"篮球"和Json串中list字段的元素"排球","足球","乒乓球"进行了合并。

@JsonRawValue

序列化时,属性值原样输出,属性值不会含转义和加引号(也就是属性值会自动去转义和去多余的引号)

@Data
public class User {
    
    

    private String id;
    private String userName;
    private String passWord;
    @JsonRawValue
    private String email;
    private String nickName;
    private Date createTime;
}
    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]\\");
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出

{
    
    
  "id" : "999",
  "userName" : "小五",
  "passWord" : "888888",
  "email" : 111111@qq.com\,
  "nickName" : null,
  "createTime" : null,
  "cardInfo" : {
    
    
    "cardType" : "1",
    "cardNum" : "123445"
  }
}

@JsonEnumDefaultValue

@Data
public class User {
    
    

    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    private SexEnum sex;
}
enum SexEnum {
    
    
    @JsonEnumDefaultValue
    MAN,
    WOMAN
}
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"id\":\"999\",\"userName\":\"小五\",\"passWord\":\"888888\",\"email\":null,\"nickName\":null,\"createTime\":null,\"sex\":\"男\"}";
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }

输出

User(id=999, userName=小五, passWord=888888, email=null, nickName=null, createTime=null, sex=MAN)

@JsonFilter

JsonFilter 注解的作用是通过属性名过滤要序列化的属性。

它指定一个过滤器的ID,通过ObjectMapper注册真正的过滤器,过滤器需要实现接口 com.fasterxml.jackson.databind.ser.PropertyFilter。一般使用SimpleBeanPropertyFilter过滤器。

SimpleBeanPropertyFilterde的主要方法:

  • serializeAllExcept:过滤掉指定字段,保留其它字段
  • filterOutAllExcept:保留指定的字段,过滤掉其它字段

1. 用于类上

@Data
@JsonFilter("userFilter")
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    private CardInfo cardInfo;
}
    private static void objectFiilter2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]");
        user.setCardInfo(new CardInfo("1", "500210190001017771"));

        SimpleFilterProvider filterProvider = new SimpleFilterProvider();
        // filterProvider.addFilter("userFilter",SimpleBeanPropertyFilter.filterOutAllExcept("passWord"));// 保留指定的字段,过滤掉其它字段
        filterProvider.addFilter("userFilter",SimpleBeanPropertyFilter.serializeAllExcept ("passWord"));// 过滤掉指定字段,保留其它字段

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        objectMapper.setFilterProvider(filterProvider);

        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出:

{
    
    
  "id" : "999",
  "userName" : "小五",
  "email" : "[email protected]",
  "nickName" : null,
  "createTime" : null,
  "cardInfo" : {
    
    
    "cardType" : "1",
    "cardNum" : "500210190001017771"
  }
}

过滤掉了
2. 用于字段上

@Data
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    @JsonFilter("userFilter")
    private CardInfo cardInfo;
}

@Data
class CardInfo {
    
    

    // @JsonValue
    private String cardType;
    private String cardNum;

    public CardInfo() {
    
    
    }

    public CardInfo(String cardType, String cardNum) {
    
    
        this.cardType = cardType;
        this.cardNum = cardNum;
    }
}
    private static void objectFiilter2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]");
        user.setCardInfo(new CardInfo("1", "500210190001017771"));

        SimpleFilterProvider filterProvider = new SimpleFilterProvider();
        filterProvider.addFilter("userFilter",SimpleBeanPropertyFilter.serializeAllExcept ("cardNum"));// 过滤掉指定字段,保留其它字段

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        objectMapper.setFilterProvider(filterProvider);

        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出:

{
    
    
  "id" : "999",
  "userName" : "小五",
  "passWord" : "888888",
  "email" : "[email protected]",
  "nickName" : null,
  "createTime" : null,
  "cardInfo" : {
    
    
    "cardType" : "1"
  }
}

@JsonSerialize

序列化时,指定字段序列化使用的序列化器。

JsonSerialize注解的部分属性:

  • using:指定非null值时使用的序列化器
  • nullsUsing:指定null值时使用的序列化器

若要自定义序列化器,一般通过继承StdSerializer或者JsonSerializer实现。

@Data
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    @JsonSerialize(using = SexEnumSerializer.class)
    private SexEnum sex;
    private String nickName;
    private Date createTime;
}

enum SexEnum {
    
    
    MAN("男"),
    WOMAN("女");

    private String value;

    SexEnum(String value) {
    
    
        this.value = value;
    }

    public String getValue() {
    
    
        return value;
    }

    public SexEnum setValue(String value) {
    
    
        this.value = value;
        return this;
    }

    public static SexEnum getByValue(String value) {
    
    
        for (SexEnum sexEnum : SexEnum.values()) {
    
    
            if (sexEnum.getValue().equals(value)) {
    
    
                return sexEnum;
            }
        }
        return null;
    }
}
// 方式1:继承StdSerializer
public class SexEnumSerializer extends StdSerializer<SexEnum> {
    
    

    public SexEnumSerializer() {
    
    
        this(null);
    }

    public SexEnumSerializer(Class<SexEnum> t) {
    
    
        super(t);
    }

    @Override
    public void serialize(SexEnum value, JsonGenerator gen, SerializerProvider provider) throws IOException {
    
    
        gen.writeString(value.getValue());
    }
}

// 方式2:继承JsonSerializer
public class SexEnumSerializer extends JsonSerializer<SexEnum> {
    
    

    @Override
    public void serialize(SexEnum value, JsonGenerator gen, SerializerProvider provider) throws IOException {
    
    
        gen.writeString(value.getValue());
    }
}
    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]");
        user.setSex(SexEnum.MAN);
        user.setCreateTime(new Date());
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出

{
    
    
  "id" : "999",
  "userName" : "小五",
  "passWord" : "888888",
  "email" : "[email protected]",
  "sex" : "男",
  "nickName" : null,
  "createTime" : 1673157947671
}

@JsonDeserialize

反序列化时,指定字段反序列化使用的反序列化器。

JsonDeserialize注解的部分属性:

  • using:指定非null值时使用的反序列化器
  • nullsUsing:指定null值时使用的反序列化器

若要自定义反序列化器,一般通过继承StdDeserializer或者JsonDeserializer实现。

@Data
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    @JsonDeserialize(using = SexEnumDeserializer.class)
    private SexEnum sex;
    private String nickName;
    private Date createTime;
}

enum SexEnum {
    
    
    @JsonEnumDefaultValue
    MAN("男"),
    WOMAN("女");

    private String value;

    SexEnum(String value) {
    
    
        this.value = value;
    }

    public String getValue() {
    
    
        return value;
    }

    public SexEnum setValue(String value) {
    
    
        this.value = value;
        return this;
    }

    public static SexEnum getByValue(String value) {
    
    
        for (SexEnum sexEnum : SexEnum.values()) {
    
    
            if (sexEnum.getValue().equals(value)) {
    
    
                return sexEnum;
            }
        }
        return null;
    }
}
// 方式1:继承StdDeserializer
public class SexEnumDeserializer extends StdDeserializer<SexEnum> {
    
    

    public SexEnumDeserializer() {
    
    
        this(null);
    }

    public SexEnumDeserializer(Class<String> t) {
    
    
        super(t);
    }

    @Override
    public SexEnum deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    
    
        String value = p.getText();
        return SexEnum.getByValue(value);
    }
}

// 方式2:继承StdDeserializer
public class SexEnumDeserializer extends JsonDeserializer<SexEnum> {
    
    

    @Override
    public SexEnum deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    
    
        String value = p.getText();
        return SexEnum.getByValue(value);
    }
}
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"id\":\"999\",\"userName\":\"小五\",\"passWord\":\"888888\",\"email\":\"[email protected]\",\"nickName\":null,\"sex\":\"女\",\"createTime\":null}";
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }

输出

User(id=999, userName=小五, passWord=888888, email=111111@qq.com, sex=WOMAN, nickName=null, createTime=null)

@JacksonAnnotation

注解上使用JacksonAnnotation表示该注解时Jackson相关注解。

所有的Jsonson注解类上都有JacksonAnnotation元注解。

@JacksonAnnotationsInside

Jackson注解的元注解,可以将其他注解封装成一个组合注解,通常用于Jackson自定义组合注解。

@Data
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    @JsonSerialize(using = SexEnumSerializer.class)
    @JsonDeserialize(using = SexEnumDeserializer.class)
    private SexEnum sex;
    private String nickName;
    private Date createTime;
}

enum SexEnum {
    
    
    MAN("男"),
    WOMAN("女");

    private String value;

    SexEnum(String value) {
    
    
        this.value = value;
    }

    public String getValue() {
    
    
        return value;
    }

    public SexEnum setValue(String value) {
    
    
        this.value = value;
        return this;
    }

    public static SexEnum getByValue(String value) {
    
    
        for (SexEnum sexEnum : SexEnum.values()) {
    
    
            if (sexEnum.getValue().equals(value)) {
    
    
                return sexEnum;
            }
        }
        return null;
    }
}

通过@JacksonAnnotationsInside自定义注解可改为

@Target({
    
    ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JsonSerialize(using = SexEnumSerializer.class)
@JsonDeserialize(using = SexEnumDeserializer.class)
@JacksonAnnotationsInside
public @interface JsonSexSerializeDeserialize {
    
    

}
@Data
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    @JsonSexSerializeDeserialize
    private SexEnum sex;
    private String nickName;
    private Date createTime;
}

enum SexEnum {
    
    
    MAN("男"),
    WOMAN("女");

    private String value;

    SexEnum(String value) {
    
    
        this.value = value;
    }

    public String getValue() {
    
    
        return value;
    }

    public SexEnum setValue(String value) {
    
    
        this.value = value;
        return this;
    }

    public static SexEnum getByValue(String value) {
    
    
        for (SexEnum sexEnum : SexEnum.values()) {
    
    
            if (sexEnum.getValue().equals(value)) {
    
    
                return sexEnum;
            }
        }
        return null;
    }
}

@JsonAppend

@JsonAppend注解用于在序列化对象时向对象添加虚拟属性。

当我们希望直接向序列化后JSON字符串中添加补充信息而不是更改类定义时,可以使用@JsonAppend。
注解的主要属性:

  • attrs:序列化时要包括的一组虚拟属性
  • props:序列化时要包括的一组通用虚拟属性
  • prepend:虚拟属性附加在常规属性前面还是右面,默认false(后面)

例1:使用attrs属性

@Data
@JsonAppend(attrs = {
    
    @JsonAppend.Attr(value = "age"),@JsonAppend.Attr(value = "sex")})
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
}
    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]");
        user.setCreateTime(new Date());
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
    
    
            String jsonStr = objectMapper.writerFor(User.class).withAttribute("age", "20").withAttribute("sex", "男").writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出

{
    
    
  "id" : "999",
  "userName" : "小五",
  "passWord" : "888888",
  "email" : "[email protected]",
  "nickName" : null,
  "createTime" : 1675151635581,
  "age" : "20",
  "sex" : "男"
}

例2:使用props属性

@Data
@JsonAppend(props = {
    
    @JsonAppend.Prop(value =TestWriter.class ,type = String.class,name = "idcard")}, prepend = true)
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
}

@NoArgsConstructor
class TestWriter extends VirtualBeanPropertyWriter {
    
    


    private TestWriter(BeanPropertyDefinition propDef, Annotations contextAnnotations, JavaType declaredType) {
    
    
        super(propDef, contextAnnotations, declaredType);
    }


    @Override
    protected Object value(Object bean, JsonGenerator gen, SerializerProvider prov) throws Exception {
    
    
        return "5002001564564565";
    }

    @Override
    public VirtualBeanPropertyWriter withConfig(MapperConfig<?> config, AnnotatedClass declaringClass, BeanPropertyDefinition propDef, JavaType type) {
    
    
        return new TestWriter(propDef, declaringClass.getAnnotations(), type);
    }
}
    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]");
        user.setCreateTime(new Date());
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出

{
    
    
  "idcard" : "5002001564564565",
  "id" : "999",
  "userName" : "小五",
  "passWord" : "888888",
  "email" : "[email protected]",
  "nickName" : null,
  "createTime" : 1675151702894
}

@JsonIdentityInfo

@JsonIdentityInfo用于处理对象的循环引用,方法是只在第一次遇到时序列化为完整的对象,之后再遇到同一个对象,都以对象的标识符代替。

生成对象标识符有两种方法:

  • 使用生成器(标准生成器或自定义生成器之一)
  • 直接使用属性的值(通过使用占位符生成器标记ObjectIdGenerators.PropertyGenerator)

对象标识目前不支持JSON数组类型(Java数组或列表)或Java Map类型。

注解的主要属性:

  • property:对象标识的属性名
  • generator:对象标识的生成器
@Data
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    private User user;
}

1. 循环引用

    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]");
        user.setCreateTime(new Date());
        user.setUser(user);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出

{
    
    
  "id" : "999",
  "userName" : "小五",
  "passWord" : "888888",
  "email" : "[email protected]",
  "nickName" : null,
  "createTime" : 1675156428169,
  "user" : "999"
}

2. 非循环引用

    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]");
        user.setCreateTime(new Date());
        User user1 = new User();
        user1.setId("888");
        user1.setUserName("小六");
        user.setUser(user1);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出

{
    
    
  "id" : "999",
  "userName" : "小五",
  "passWord" : "888888",
  "email" : "[email protected]",
  "nickName" : null,
  "createTime" : 1675156549005,
  "user" : {
    
    
    "id" : "888",
    "userName" : "小六",
    "passWord" : null,
    "email" : null,
    "nickName" : null,
    "createTime" : null,
    "user" : null
  }
}

@JsonIdentityReference

@JsonIdentityReference 必须与 @JsonIdentityInfo 一起使用。

@JsonIdentityInfo在第二次遇到时才序列化为对象标识,@JsonIdentityReference可以强制序列化为对象标识,而不是将第一个实例序列化为完整的POJO。

注解的主要属性:

  • alwaysAsId:是否总是序列化为对象标识,默认false。当为true时,在第一次时就会序列化为对象标识,而不是等到第二次cai序列化为对象标识(@JsonIdentityInfo的规则)

注意事项:

  • 使用@JsonIdentityInfo标识遇到循环引用时,将第一个实例序列化为完整的POJO,第二次才序列化为对象标识。
  • 如果加上了@JsonIdentityReference,表示第一次就直接序列化为对象标识(无论是否是循环引用)
@Data
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = true)
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;
    private User user;
}

1. 循环引用

    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]");
        user.setCreateTime(new Date());
        user.setUser(user);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出

"999"

2. 非循环引用

    private static void object2JsonStr() {
    
    
        User user = new User();
        user.setId("999");
        user.setUserName("小五");
        user.setPassWord("888888");
        user.setEmail("[email protected]");
        user.setCreateTime(new Date());
        User user1 = new User();
        user1.setId("888");
        user1.setUserName("小六");
        user.setUser(user1);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
    
    
            String jsonStr = objectMapper.writeValueAsString(user);
            System.out.println(jsonStr);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

输出

"999"

@JsonBackReference

与下面@JsonManagedReference一起分析

@JsonManagedReference

Jackson中的@JsonBackReference和@JsonManagedReference,以及@JsonIgnore均是为了解决对象中存在双向引用导致的无限递归问题。这些标注均可用在属性或对应的get、set方法中。

@JsonBackReference和@JsonManagedReference两个标注通常配对使用,通常用在父子关系中。

@JsonIgnore、@JsonBackReference、@JsonManagedReference对比:

  • @JsonIgnore:直接忽略某个属性,以断开无限递归,序列化或反序列化均忽略。

    当然如果标注在get、set方法中,则可以分开控制,序列化对应的是get方法,反序列化对应的是set方法。

    在父子关系中,当反序列化时,@JsonIgnore不会自动注入被忽略的属性值(父或子),这是它跟@JsonBackReference和@JsonManagedReference最大的区别。

  • @JsonBackReference:@JsonBackReference标注的属性在序列化时,会被忽略。

    在序列化时,@JsonBackReference的作用相当于@JsonIgnore,此时可以没有@JsonManagedReference。

    但在反序列化(deserialization,即json数据转换为对象)时,如果没有@JsonManagedReference,则不会自动注入@JsonBackReference标注的属性(被忽略的父或子)

  • @JsonManagedReference:用于在反序列化时,自动注入@JsonBackReference标注的属性

public class Test {
    
    
    public static void main(String[] args) throws IOException {
    
    

        Order order = new Order();
        Customer customer = new Customer();

        customer.setId(2);
        customer.setName("Peter");
        customer.setOrder(order);

        order.setOrderId(1);
        order.setItemIds(Stream.of(10, 30).collect(Collectors.toList()));
        order.setCustomer(customer);

        ObjectMapper om = new ObjectMapper();
        String serializing = om.writeValueAsString(customer);

        Customer deserializing = om.readValue(serializing, Customer.class);
    }
}

@Data
class Customer {
    
    
    private int id;
    private String name;
    @JsonManagedReference
    private Order order;
}

@Data
class Order {
    
    
    private int orderId;
    private List<Integer> itemIds;
    @JsonBackReference
    private Customer customer;
}

调试过程:
在这里插入图片描述
可见:

  • 序列化时,忽略了order中的customer属性
  • 反序列化时,又自动注入了order中的customer属性

@JsonPOJOBuilder

@JsonPOJOBuilder注解用于配置构建器类,以自定义JSON文档的反序列化,以便在命名约定与默认约定不同的情况下恢复POJO。

@JsonPOJOBuilder主要用与bean的属性名称与JSON字符串中的字段名称不同的场景。

注解的主要属性:

  • buildMethodName: 无参数方法的名称,用于在将JSON字段绑定到bean的属性之后实例化预期的bean。默认名称为“build”。
  • withPrefix: 用于自动检测JSON和bean属性之间的匹配的名称前缀。默认前缀是 with。
@Data
@JsonDeserialize(builder = UserBuilder.class)
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    private String nickName;
    private Date createTime;

    public User() {
    
    
    }

    public User(String id, String userName) {
    
    
        this.id = id;
        this.userName = userName;
    }
}

@JsonPOJOBuilder(buildMethodName = "createBean", withPrefix = "construct")
class UserBuilder {
    
    
    private String userId;
    private String name;

    public UserBuilder constructUserId(String userId) {
    
    
        this.userId = userId;
        return this;
    }

    public UserBuilder constructName(String name) {
    
    
        this.name = name;
        return this;
    }

    public User createBean() {
    
    
        return new User(userId, name);
    }
}
    private static void jsonStr2Object() {
    
    
        String jsonStr = "{\"userId\":\"999\",\"name\":\"小五\"}";
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
        try {
    
    
            User user = objectMapper.readValue(jsonStr, User.class);
            System.out.println(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
    }

输出

User(id=999, userName=小五, passWord=null, email=null, nickName=null, createTime=null)

3. 自定义Jackson组合注解

Jackson通过JacksonAnnotationsInside注解来自定义Jackson组合注解。

例如:自定义Jackson组合注解:JsonSexSerializeDeserialize。

该注解的作用:

  • 序列化时,将枚举对象SexEnum转化为字符串值"男"或"女"
  • 反序列化时,将字符串值"男"或"女"转化为枚举对象SexEnum
@Target({
    
    ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JsonSerialize(using = SexEnumSerializer.class)
@JsonDeserialize(using = SexEnumDeserializer.class)
@JacksonAnnotationsInside
public @interface JsonSexSerializeDeserialize {
    
    

}
public class SexEnumSerializer extends JsonSerializer<SexEnum> {
    
    

    @Override
    public void serialize(SexEnum value, JsonGenerator gen, SerializerProvider provider) throws IOException {
    
    
        gen.writeString(value.getValue());
    }
}
public class SexEnumDeserializer extends JsonDeserializer<SexEnum> {
    
    

    @Override
    public SexEnum deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    
    
        String value = p.getText();
        return SexEnum.getByValue(value);
    }
}
@Data
public class User {
    
    
    private String id;
    private String userName;
    private String passWord;
    private String email;
    @JsonSexSerializeDeserialize
    private SexEnum sex;
    private String nickName;
    private Date createTime;
}

enum SexEnum {
    
    
    MAN("男"),
    WOMAN("女");

    private String value;

    SexEnum(String value) {
    
    
        this.value = value;
    }

    public String getValue() {
    
    
        return value;
    }

    public SexEnum setValue(String value) {
    
    
        this.value = value;
        return this;
    }

    public static SexEnum getByValue(String value) {
    
    
        for (SexEnum sexEnum : SexEnum.values()) {
    
    
            if (sexEnum.getValue().equals(value)) {
    
    
                return sexEnum;
            }
        }
        return null;
    }
}

Guess you like

Origin blog.csdn.net/JokerLJG/article/details/128573849