Jackson注解使用分析

news2024/7/6 19:43:00

文章目录

  • Jackson常用注解
    • 1. 常用注解汇总
    • 2. 注解使用分析
      • @JsonInclude
      • @JsonAnyGetter
      • @JsonAnySetter
      • @JsonNaming
      • @JsonAutoDetect
      • @JacksonInject
      • @JsonAlias
      • @JsonValue
      • @JsonMerge
      • @JsonRawValue
      • @JsonEnumDefaultValue
      • @JsonFilter
      • @JsonSerialize
      • @JsonDeserialize
      • @JacksonAnnotation
      • @JacksonAnnotationsInside
      • @JsonAppend
      • @JsonIdentityInfo
      • @JsonIdentityReference
      • @JsonBackReference
      • @JsonManagedReference
      • @JsonPOJOBuilder
    • 3. 自定义Jackson组合注解


Jackson常用注解

1. 常用注解汇总

注解作用范围主要属性描述
JsonProperty字段、方法value:指定json字段名
access:指定权限
required:
index:
defaultValue:
指定序列化、反序列化字段Json字段名
JsonPropertyOrdervalue:字段顺序数组,未配字段排在后面指定序列化时字段排序
JsonIgnore字段、get与set方法value:默认为true,为false不忽略指定序列化、反序列化忽略字段
JsonIgnoreTypevalue:默认为true,为false不忽略指定序列化、反序列化忽略类型(当该类作为别的类的属性时,忽略该类的所有字段)
JsonIgnorePropertiesvalue: 数组,指定要忽略的字段
ignoreUnknown:默认false,忽略不知道字段
allowGetters: 默认false,允许从get方法获取值
allowSetters:默认false,允许set方法设置值
指定序列化、反序列化忽略字段集合
JsonGettergetter方法value:指定json字段名指定序列化时的Json字段名,用于get方法上,优先级高于@JsonProperty
JsonSettersetter方法value:指定json字段名指定反序列化时的Json字段名,用于set方法上,优先级高于@JsonProperty
JsonInclude类、字段、方法value:序列化规则指定序列化规则
JsonRootNamevalue:根节点名称指定序列化、反序列化的根节点名称
JsonFormat字段、方法、参数pattern:时间格式
timezone:时区
设置序列化时的时间格式化格式
JsonAnyGetter方法enabled:是否启用,默认true作用于方法上,可以灵活地把类型为Map的属性作为标准属性序列化到JSON字符串中。方法返回值必须是Map。序列化时将Map中的key/value对展开到当前类的同一级
JsonAnySetter方法、字段enabled:是否启用,默认true一般作用于方法上,方法的入参必须有key、value。反序列化时,Json中与类不匹配的属性将会调用指定JsonAnySetter注解的方法,传入属性和属性值
JsonNamingvalue:属性命名策略指定序列化、反序列化的属性命名策略。
JsonCreator构造方法mode:指定模式指定反序列化使用的构造方法,需和JsonProperty注解配合使用,如:
@JsonCreator
public User(@JsonProperty(“id”)String id) {…}
JsonAutoDetect指定字段、方法的可见性
JsonUnwrapped字段、方法、参数enabled:是否开启,默认true
prefix:属性名称前缀
suffix:属性名称后缀
将其属性上拉移一个层级展开
JacksonInject字段、方法、参数value:字段标识
userInput:Json属性值是否覆盖默认值,默认TRUE
指定反序列化时,Json字段值是否覆盖实体类属性默认值
JsonAlias字段、方法、参数value:别名集合反序列化时,指定能匹配实体类属性的多个Json字段名称
JsonValue字段、方法value:是否启用一个类只能用一个,当加上JsonValue注解时,序列化时只返回这一个字段的值,而不是这个类的所有属性键值对。
一个类最多只能有一个JsonValue注解,否则会抛出异常;但多个类中可同时有一个JsonValue注解,序列化正常
JsonMerge字段、方法、参数value:是否启用合并反序列化时,将Json集合字段的元素与实体类对应属性默认元素合并
JsonRawValue字段、方法value:是否启用序列化时,属性值原样输出,属性值不会含转义和加引号(也就是属性值会自动去转义和去多余的引号)
JsonEnumDefaultValue字段-反序列化时,当枚举字段遇到未知的枚举值,使用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
JsonAppendattrs:序列化时要包括的一组虚拟属性
props:序列化时要包括的一组通用虚拟属性
prepend:虚拟属性附加在常规属性前面还是右面,默认false(后面)
用于在序列化对象时向对象添加虚拟属性
JsonIdentityInfo类、字段、方法、参数property:对象标识的属性名
generator:对象标识的生成器
用于处理对象的循环引用(序列化、反序列化),在第一次遇到时序列化为完整的对象,之后再遇到同一个对象,都以对象的标识符代替。能解决一对一、一对多、多对多的循环引用
JsonIdentityReference类、字段、方法、参数alwaysAsId:是否总是序列化为对象标识可以强制序列化为对象标识,而不是将第一个实例序列化为完整的 POJO,第二次才序列化为对象标识。必须与@JsonIdentityInfo 一起使用
JsonBackReference字段、方法@JsonBackReference标注的属性在序列化(serialization,即将对象转换为json数据)时,会被忽略(即结果中的json数据不包含该属性的内容)。
在序列化时,@JsonBackReference的作用相当于@JsonIgnore
JsonManagedReference字段、方法如果有@JsonManagedReference,则会自动注入@JsonBackReference标注的属性
JsonPOJOBuilderbuildMethodName: 无参数方法的名称,用于在将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", "1111@qq.com");
        user.addOther("email1", "2222@qq.com");
        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" : "2222@qq.com",
  "email" : "1111@qq.com"
}

@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\":\"111111@qq.com\",\"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("111111@qq.com\\");
        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("111111@qq.com");
        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" : "111111@qq.com",
  "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("111111@qq.com");
        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" : "111111@qq.com",
  "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("111111@qq.com");
        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" : "111111@qq.com",
  "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\":\"111111@qq.com\",\"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("111111@qq.com");
        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" : "111111@qq.com",
  "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("111111@qq.com");
        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" : "111111@qq.com",
  "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("111111@qq.com");
        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" : "111111@qq.com",
  "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("111111@qq.com");
        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" : "111111@qq.com",
  "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("111111@qq.com");
        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("111111@qq.com");
        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;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/195075.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

excel合并技巧:查找函数遇到合并单元格怎么应对

大家都在期盼奖金的到来&#xff0c;可是核算奖金的同事正在苦恼&#xff0c;因为以前用得好好的VLOOKUP函数突然不合适了&#xff0c;很多人的奖金计算出来都变成了乱码&#xff1a;使用VLOOKUP函数每个部门只有第一行正确&#xff0c;其他都是乱码。看到这个表&#xff0c;相…

【服务器数据恢复】raid5硬盘离线后热备盘未启用的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌X3850服务器&#xff0c;组建的raid5磁盘阵列&#xff0c;该raid5磁盘阵列包含4块成员盘和1块热备盘。 服务器故障&#xff1a; 服务器在运行过程中由于未知原因突然崩溃&#xff0c;用户方工程师检查后发现该故障服务器raid5阵列中2块磁…

Electron + Vue 开发环境搭建

1.安装nodejs&#xff0c;下载网址&#xff1a;https://nodejs.org/en/ 点击安装程序&#xff0c;一路next即可 安装完成之后打开cmd测试&#xff0c;输入node -v查看node版本&#xff0c;输入npm -v查看npm版本 安装完成后&#xff0c;.msi格式的安装包已经将node.exe添加到…

Excel连接openGauss数据库实操

目录 前言 一、通过excel 添加数据源访问openGauss 1、查看Excel版本 2、下载 ODBC驱动 3、安装ODBC驱动 4、添加ODBC数据源 5、在excel中添加数据源&#xff08;访问openGauss&#xff09; 二、通过excel 的VBA&#xff08;宏&#xff09;访问openGauss 1、宏权限设置…

2.1 java基础 day02 流程控制 创建类和对象 栈堆元空间

1流程控制 流程控制&#xff1a; 1.1.计算机在执行代码时对指令代码执行顺序的控制 1.2.Java 流程控制主要分三种&#xff1a; 顺序执行 分支执行 重复执行 1.3.顺序执行 按代码和语法出现的先后顺序执行 1.4.分支执行 根据判断条件执行分支逻辑 可选分支、必选分支&#…

活体识别6:小视科技开源的静默活体检测

说明 该项目为小视科技的静默活体检测项目。开源地址在 https://github.com/minivision-ai/Silent-Face-Anti-Spoofing。 由于不是论文衍生项目&#xff0c;所以只有一个公众号文章的介绍&#xff1a;https://mp.weixin.qq.com/s/IoWxF5cbi32Gya1O25DhRQ 方案详情 该方案是…

【安全】端口复用:远程遥控iptablesSSLH工具

目录 基础知识点 链的概念 表的概念 表链关系 远程遥控iptables进行端口复用 Ⅰ、利用ICMP做遥控开关 ①创建端口复用链 ②创建端口复用规则&#xff0c;将流量转发至 22 端口 ③开启开关&#xff0c;如果接收到一个长为 1139 的 ICMP 包&#xff0c;则将来源 IP 添加到…

使用Oracle VM VirtualBox安装Centos

1.下载安装Oracle VM VirtualBox 2.下载Centos 下载地址 旧版本 3.新建 选择镜像填写账户信息之后&#xff0c;我这边不知道什么原因&#xff0c;并不能完成所有工作&#xff0c;所以我一般不选择 4.选择镜像 5.安装 通过方向键和回车键选择 6.设置 选择中文 等待一些自动…

2023年“华数杯”国际大学生数学建模B题完整思路

2023华数杯如期开赛&#xff0c;本次比赛作为美赛的模拟赛&#xff0c;赛题和比赛时间都和美赛高度相似&#xff0c;因此大家 完全可以当作一次美赛之前的练习赛进行。美赛的发题时间与华数杯一致&#xff0c;都是早晨六点&#xff0c;现已经将机器翻译的初步翻译 结果进行了分…

c语言通讯录max——数据的持久化处理(详解)

用文件操作升级通讯录前言1.实现逻辑2.用哪种文件存储数据2. save_contact函数设计3. load_contact 函数设计5.代码总览contact.hcontact.ctext.c前言 在有关通讯录的上一篇博客中&#xff0c;作者用柔性数组实现了动态改变通讯录占用空间的功能&#xff0c;但是在最后还是留下…

【Go基础】Http编程

文章目录1. http协议1.1 请求方法1.2 URL1.3 协议版本1.4 请求头1.5 请求正文1.6 http response1.7 https2. go语言http标准库3. http router4. 请求校验5. http中间件6. GIN6.1 路由6.2 参数获取6.3 利用postman提交http请求6.4 生成response6.5 参数检验6.6 中间件6.7 会话7.…

互联网分层模型

互联网的逻辑实现被分为好几层。每一层都有自己的功能&#xff0c;就像建筑物一样&#xff0c;每一层都靠下一层支持。用户接触到的只是最上面的那一层&#xff0c;根本不会感觉到下面的几层。要理解互联网就需要自下而上理解每一层的实现的功能。如上图所示&#xff0c;互联网…

55.Isaac教程--Livox 激光雷达

Livox 激光雷达 ISAAC教程合集地址文章目录Livox 激光雷达支持的硬件和固件在桌面上设置和运行示例应用程序在机器人上设置和运行示例应用程序查看正在运行的应用程序将来Livox 激光雷达 Isaac SDK 支持使用 Livox LIDAR&#xff0c;包括兼容的驱动程序和示例应用程序。 支持的…

Android马甲包的那些事儿

制作Android马甲包最简单的方式就是使用 productFlavors 机制。本文就是在productFlavors机制的基础上制作的马甲包&#xff0c;每个马甲只需要在build.gradle文件中配置一下包名、各种key、签名文件配置启动页、logo、app名等资源配置服务器域名、微信分享回调Activity等代码此…

Windows上tensorflow的GPU死活引用不了(tensorflow 2.11无法调用GPU)

tensorflow对于gpu的支持只到2.10&#xff0c;如果你装了最新的tf(2.11)&#xff0c;需要先卸载2.11。 安装代码&#xff1a; pip install tensorflow2.10 -i https://pypi.tuna.tsinghua.edu.cn/simple/解决过程&#xff1a; 查看CUDA与cuDNN配套版本&#xff1a; https:/…

解决ModuleNotFoundError: No module named ‘pygame‘问题

一、问题描述在开发环境运行Python的源码游戏时&#xff0c;游戏不能正常运行&#xff0c;且提示&#xff08;ModuleNotFoundError: No module named pygame【没有发现模块错误&#xff1a;没有发现名为pygame的模块】&#xff09;如下图所示&#xff1a;二、问题分析通过查看提…

OpenCV实战——基于均值漂移算法检测图像内容

OpenCV实战——基于均值漂移算法检测图像内容0. 前言1. 均值漂移算法2. 检测图像内容3. 完整代码相关链接0. 前言 直方图反投影的结果是一个概率图&#xff0c;表示在特定图像位置找到给定图像内容的概率。假设我们现在知道一个物体在图像中的大概位置&#xff1b;概率图可用于…

在 Navicat Monitor for MySQL/MariaDB 中配置实例

Navicat Monitor for MySQL/MariaDB 是一个无代理的远程服务器监控工具&#xff0c;它包含的功能可以使监控数据库&#xff08;DB&#xff09;实例发挥最大效用和更轻松。此外&#xff0c;基于服务器的架构使其可以通过网页浏览器从任何地方访问&#xff0c;从而为你提供无障碍…

DaVinci 项目设置:图像缩放调整

项目设置/图像缩放调整Project Settings/Image Scaling图像缩放调整 Image Scaling选项卡可用于设置片段在输入、输出时的缩放及相应的插值算法。图像缩放调整Image Scaling主要用于选择缩放处理的插值方法&#xff0c;也可用于载入输入、输出缩放调整的预设。缩放过滤器Resize…

特别提醒|2023年考PMP需关注的5大问题

目前知道的是2023年考试时间为3月、5月、8月、11月&#xff0c;但是3月不给新报名&#xff0c;需要报名的话&#xff0c;就是报5月的考试了。当然有的伙伴会有一些小问题&#xff0c;这里给大家整理了一些基本的问题给大家回答一下&#xff0c;大家如果还有其他的问题可以评论提…