java:jackson 四:Jackson Property Inclusion Annotations

本文介绍了Jackson库中用于控制JSON序列化行为的各种注解,包括@JsonIgnoreProperties、@JsonIgnore、@JsonIgnoreType、@JsonInclude、@JsonAutoDetect和@JsonFilter等,并提供了详细的示例说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java:jackson 四:Jackson Property Inclusion Annotations

1 前言

参考文档地址:

https://www.baeldung.com/jackson

https://www.baeldung.com/jackson-annotations

SpringBoot自带的jackson版本如下:

<parent>
    <artifactId>spring-boot-starter-parent</artifactId>
    <groupId>org.springframework.boot</groupId>
    <version>2.5.4</version>
</parent>

在这里插入图片描述

或者不使用SpringBoot情况下,单独配置jackson-databind版本:

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <jackson-databind.version>2.14.1</jackson-databind.version>
</properties>
    
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson-databind.version}</version>
</dependency>

同时使用SpringBoot和自定义的jackson版本时,注意避免依赖冲突。

2 使用


2.1 @JsonIgnoreProperties

@JsonIgnoreProperties is a class-level annotation that marks a property or a list of properties that Jackson will ignore.

因此@JsonIgnoreProperties在类上使用时,可以忽略字段:

如下序列化时,必须有对应的Getter方法:

@JsonIgnoreProperties(value = {"id","value"})
@AllArgsConstructor
@Getter
class JacksonVO {
    int id;

    String fruitName;

    int age;

    String value;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
    Date day;

    @Override
    public String toString(){
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
JacksonVO jacksonVO = new JacksonVO(1,"apple", 22, "nihao", new Date());
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));

执行结果:

JacksonVO[age=22,day=Thu Dec 29 16:40:49 CST 2022,fruitName=apple,id=1,value=nihao]
{
  "fruitName" : "apple",
  "age" : 22,
  "day" : "2022-12-29 16:40:49"
}

2.2 @JsonIgnore

In contrast, the @JsonIgnore annotation is used to mark a property to be ignored at the field level.

可见,@JsonIgnore使用于Field上的,如下:

@JsonIgnoreProperties(value = {"id","value"})
@AllArgsConstructor
@Getter
class JacksonVO {
    int id;

    String fruitName;

    @JsonIgnore
    int age;

    String value;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai")
    Date day;

    @Override
    public String toString(){
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
JacksonVO jacksonVO = new JacksonVO(1,"apple", 22, "nihao", new Date());
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));

执行结果:

JacksonVO[age=22,day=Thu Dec 29 16:51:40 CST 2022,fruitName=apple,id=1,value=nihao]
{
  "fruitName" : "apple",
  "day" : "2022-12-29 16:51:40"
}

2.3 @JsonIgnoreType

@JsonIgnoreType marks all properties of an annotated type to be ignored.

We can use the annotation to mark all properties of type Name to be ignored:

@Getter
@Setter
@AllArgsConstructor
class JacksonVO1 {
    int id;
    JacksonVO2 vo2;

    @JsonIgnoreType
    @Getter
    @Setter
    @AllArgsConstructor
    static class JacksonVO2{
        int jid;
        String name;

        @Override
        public String toString(){
            return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
        }
    }

    @Override
    public String toString(){
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
JacksonVO1 jacksonVO = new JacksonVO1(1,new JacksonVO1.JacksonVO2(123,"xiaoxu"));
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));

执行结果:

JacksonVO1[id=1,vo2=JacksonVO1.JacksonVO2[jid=123,name=xiaoxu]]
{
  "id" : 1
}

2.4 @JsonInclude

We can use @JsonInclude to exclude properties with empty/null/default values.

Let’s look at an example excluding nulls from serialization:

@Getter
@JsonInclude(JsonInclude.Include.NON_NULL)
@AllArgsConstructor
class JacksonVO2 {
    int id;
    String name;
    Boolean flag;
    String value;

    @Override
    public String toString(){
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
JacksonVO2 jacksonVO = new JacksonVO2(1, "xiaoxu", null, null);
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));

执行结果:

JacksonVO2[flag=<null>,id=1,name=xiaoxu,value=<null>]
{
  "id" : 1,
  "name" : "xiaoxu"
}

@JsonInclude除了作用在类上,亦可作用在Field上:

修改DTO:

@Getter
@AllArgsConstructor
class JacksonVO2 {
    int id;
    String name;
    @JsonInclude(JsonInclude.Include.NON_NULL)
    Boolean flag;
    String value;

    @Override
    public String toString(){
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}

再次执行:

JacksonVO2[flag=<null>,id=1,name=xiaoxu,value=<null>]
{
  "id" : 1,
  "name" : "xiaoxu",
  "value" : null
}

2.5 @JsonAutoDetect

@JsonAutoDetect can override the default semantics of which properties are visible and which are not.

First, let’s take a look at how the annotation can be very helpful with a simple example; let’s enable serializing private properties.

DTO含有private字段:

@Getter
@AllArgsConstructor
@JsonAutoDetect
class JacksonVO3 {
    private int id;
    private String name;
    private Boolean flag;
    String value;

    @Override
    public String toString(){
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
JacksonVO3 jacksonVO =new JacksonVO3(1, "xiaoxu", Boolean.TRUE, "value1");
System.out.println(jacksonVO);
System.out.println(objectMapper.writeValueAsString(jacksonVO));

执行结果:

JacksonVO3[flag=true,id=1,name=xiaoxu,value=value1]
{
  "id" : 1,
  "name" : "xiaoxu",
  "flag" : true,
  "value" : "value1"
}

2.6 @JsonFilter

The @JsonFilter annotation specifies a filter to use during serialization.

First, we define the entity and we point to the filter.

Now in the full test, we define the filter, which excludes all other properties except name from serialization.

如果需要根据场景自定义字段是否展示(比如A场景不展示这个字段,但是B场景需要展示这个字段,如果固定配置为@JsonIgnore,或者@JsonIgnoreProperties(value = {“id”,“value”}),反而不够灵活),此时可考虑@JsonFilter注解(自定义Filter,实现自定义序列化展示,根据场景选择是否需要使用该filter即可)

@Getter
@AllArgsConstructor
@JsonAutoDetect
@JsonFilter(value = "xiaoxuFilter")
class JacksonVO3 {
    private int id;
    private String name;
    private Boolean flag;
    String value;

    @Override
    public String toString(){
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
/* 序列化时,仅保留 "id","name","flag" 三个字段  */
FilterProvider filter = new SimpleFilterProvider()
        .addFilter("xiaoxuFilter",
                SimpleBeanPropertyFilter.filterOutAllExcept("id","name","flag"));

JacksonVO3 jacksonVO = new JacksonVO3(1, "xiaoxu", Boolean.TRUE, "value1");
System.out.println(jacksonVO);
System.out.println(objectMapper.writer(filter).writeValueAsString(jacksonVO));

执行结果:

JacksonVO3[flag=true,id=1,name=xiaoxu,value=value1]
{
  "id" : 1,
  "name" : "xiaoxu",
  "flag" : true
}

使用另外的filter,更灵活:

/* 序列化时,仅保留 "id","name","flag" 三个字段  */
FilterProvider filter = new SimpleFilterProvider()
        .addFilter("xiaoxuFilter",
                SimpleBeanPropertyFilter.filterOutAllExcept("id","name","flag"));

/* 序列化时,除了"id","name"不展示,其余均展示 */
SimpleBeanPropertyFilter filter1 = SimpleBeanPropertyFilter
        .serializeAllExcept("id","name");
FilterProvider filter2 = new SimpleFilterProvider()
        .addFilter("xiaoxuFilter",filter1);

JacksonVO3 jacksonVO = new JacksonVO3(1, "xiaoxu", Boolean.TRUE, "value1");
System.out.println(jacksonVO);
System.out.println(objectMapper.writer(filter2).writeValueAsString(jacksonVO));

执行结果:

JacksonVO3[flag=true,id=1,name=xiaoxu,value=value1]
{
  "flag" : true,
  "value" : "value1"
}

### Spring Boot 中 Mapper 配置及使用方法 Spring Boot 中的 Mapper 配置和使用主要依赖于 MyBatis 框架,通过 MyBatis 的注解或 XML 文件实现数据库交互。以下是详细的配置和使用方法。 #### 1. 引入依赖 在 `pom.xml` 文件中引入 MyBatis 和 Spring Boot 的整合依赖: ```xml <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.3.0</version> </dependency> ``` 此外,还需要根据数据库类型引入相应的 JDBC 驱动。例如,对于 MySQL 数据库: ```xml <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> ``` #### 2. 配置数据源 在 `application.yml` 或 `application.properties` 文件中配置数据源信息。例如: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver ``` #### 3. Mapper 接口定义 Mapper 接口是 MyBatis 的核心组件之一,用于定义 SQL 操作方法。以下是一个示例: ```java package com.example.mapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import com.example.entity.User; @Mapper public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") User findById(Integer id); } ``` 上述代码中,`@Mapper` 注解标记该接口为 MyBatis 的 Mapper 接口,Spring Boot 会自动扫描并生成其实现类[^3]。 #### 4. 启用 Mapper 扫描 在 Spring Boot 应用启动类上添加 `@MapperScan` 注解以指定 Mapper 接口所在的包路径: ```java package com.example; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.example.mapper") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` #### 5. 测试类编写 编写单元测试类以验证 Mapper 功能是否正常。例如: ```java package com.example; import com.example.mapper.UserMapper; import com.example.entity.User; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class UserMapperTest { @Autowired private UserMapper userMapper; @Test public void testFindById() { User user = userMapper.findById(1); System.out.println(user); } } ``` #### 6. 高级配置 如果需要更复杂的 SQL 查询,可以通过 XML 文件定义 SQL 语句,并在 Mapper 接口中引用。例如,在 `resources/mapper/UserMapper.xml` 文件中定义查询语句: ```xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.example.mapper.UserMapper"> <select id="findAllUsers" resultType="com.example.entity.User"> SELECT * FROM user </select> </mapper> ``` 然后在 Mapper 接口中声明对应的方法: ```java List<User> findAllUsers(); ``` #### 7. Jackson 配置(可选) 如果需要对返回的 JSON 数据进行特殊处理,可以在 `application.yml` 中进行 Jackson 配置[^5]。例如: ```yaml spring: jackson: property-naming-strategy: SNAKE_CASE default-property-inclusion: non_null ``` 以上配置将自动将驼峰命名转换为下划线命名,并忽略空值字段。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值