@JsonIgnore,@JsonProperty, @JsonInclude,@JsonFormat

参考示例

需要引入

java 复制代码
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;

功能互补:

@JsonIgnore是完全忽略某个字段,

@JsonProperty是显式指定字段的序列化/反序列化名称

经常成对出现:在实体类中,这两个注解经常被一起讨论和使用

命名相似性:都有 "Property" 这个词,容易让人联想到它们是一组相关注解

java 复制代码
public class User {
    @JsonIgnore          // 完全忽略这个字段,不参与JSON序列化/反序列化
    private String password;
    
    @JsonProperty("user_name")  // 序列化时使用 "user_name" 而不是 "userName"
    private String userName;
    
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) // 只允许反序列化,不允许序列化
    private String email;
}

@JsonIgnoreProperties

关系:@JsonIgnoreProperties是类级别的注解,@JsonIgnore是字段级别的

用途:@JsonIgnoreProperties({"field1", "field2"})可以忽略多个字段

@JsonInclude

关系:控制字段在什么情况下才被包含在JSON中

对比:@JsonIgnore是完全排除,@JsonInclude是条件性包含

@Transient(JPA注解)

混淆点:很多人会把 JPA 的 @Transient和 Jackson 的 @JsonIgnore搞混

区别:@Transient表示数据库忽略该字段,@JsonIgnore表示JSON序列化忽略该字段

这是 @Transient最核心的用途。当使用 JPA(如 Hibernate)操作数据库时,它会将实体类的字段与数据库表的列进行映射。如果你有一些字段不需要存储到数据库,只是用于在业务逻辑中临时计算或展示,就需要用到 @Transient。

java 复制代码
import javax.persistence.Transient; // JPA 标准
// 或者
import org.hibernate.annotations.Transient; // Hibernate 扩展(功能类似)

告诉 JPA/Hibernate:"这个字段是临时的,请不要为它创建数据库列,在插入和更新时也请忽略它。"

java 复制代码
import javax.persistence.*;
import lombok.Data;

@Entity
@Table(name = "sys_user")
@Data
public class SysUser {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long userId;
    
    private String userName;
    
    private String nickName;
    
    // ... 其他数据库字段 (email, phonenumber, etc.)
    
    /**
     * 临时字段:全名
     * 这个字段不会映射到数据库的 'sys_user' 表中
     * 我们只是在内存中用它来拼接 userName 和 nickName
     */
    @Transient
    private String fullName;
    
    // 一个用于业务逻辑的方法
    public String getFullName() {
        if (this.fullName == null) {
            // 如果 fullName 为空,则动态拼接
            return this.userName + "(" + this.nickName + ")";
        }
        return this.fullName;
    }
}

在这个例子中:

数据库表 sys_user不会有 full_name这一列。

当你执行 userRepository.save(user)时,fullName的值不会被存入数据库。

当你从数据库查询出一个 SysUser对象时,fullName字段会是 null(除非你在查询后手动调用 getFullName()方法为其赋值)

java 复制代码
@Entity
@Table(name = "sys_user")
@Data
public class SysUser {
    
    @Id
    private Long userId;
    
    private String userName;
    
    // 1. 密码字段:需要存在数据库中,但不应通过API返回给前端
    private String password;
    
    // 2. 临时计算字段:不应存入数据库,但可能需要返回给前端
    @Transient
    private String displayName;
    
    // 3. 敏感且临时的字段:既不存数据库,也不返回给前端
    @Transient
    @JsonIgnore
    private String tempSecretKey; 

    // Getter 方法,用于业务逻辑
    public String getDisplayName() {
        return this.nickName + " (" + this.userName + ")";
    }
}

password: 会被存入数据库,但通过 API 返回时会被 @JsonIgnore过滤掉。

displayName: 不会被存入数据库(因为有 @Transient),但可以被序列化为 JSON 返回给前端(因为没有 @JsonIgnore)。

tempSecretKey: 既不会被存入数据库(因为有 @Transient),也不会出现在任何 API 的 JSON 中(因为有 @JsonIgnore)。

@JsonInclude

这是 Jackson 库中的一个注解,用于控制 JSON 序列化时哪些字段应该包含在输出中。

控制序列化时忽略空值或空集合字段,使 JSON 输出更简洁。

java 复制代码
public enum Include {
    ALWAYS,                    // 总是包含(默认)
    NON_NULL,                  // 不为 null 时包含
    NON_ABSENT,                // 不为 null 或 Optional.absent 时
    NON_EMPTY,                 // 不为空时(最常用)
    NON_DEFAULT,               // 不是默认值时
    CUSTOM,                    // 自定义规则
    USE_DEFAULTS               // 使用默认设置
}
java 复制代码
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;

@Data
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class User {
    private Long id;
    private String name;
    private String email;
    private List<String> hobbies = new ArrayList<>();
    private Map<String, Object> attributes = new HashMap<>();
    private String emptyString = "";
    private Integer zeroValue = 0;
    private Boolean falseValue = false;
    private int[] emptyArray = new int[0];
}

// 测试
User user = new User();
user.setId(1L);
user.setName(null);  // null
user.setEmail("");   // 空字符串
user.setHobbies(new ArrayList<>());  // 空列表

ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);

// 输出结果:
// {"id":1}  // 只有 id 被序列化
// name=null, email="", hobbies=[] 等都被忽略

类级别

java 复制代码
@JsonInclude(JsonInclude.Include.NON_EMPTY)
@Data
public class ApiResponse<T> {
    private boolean success;
    private String code;
    private String message;
    private T data;
    private List<String> errors = new ArrayList<>();
    
    // 返回结果会很干净
}

// 成功时
ApiResponse<User> success = ApiResponse.success(user);
// 输出:{"success":true,"code":"200","data":{...}}

// 失败时(无错误详情)
ApiResponse<Void> error = ApiResponse.error("系统错误");
// 输出:{"success":false,"code":"500","message":"系统错误"}
// errors=[] 被忽略

字段级别

java 复制代码
@Data
public class ProductDetail {
    private Long id;
    private String name;
    
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private String description;  // 只有这个字段应用 NON_EMPTY
    
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private List<String> tags;  // 这个字段用 NON_NULL
    
    private BigDecimal price = BigDecimal.ZERO;  // 默认规则
}

@JsonFormat

这是 Jackson 库中用于控制日期时间序列化和反序列化格式的注解。

java 复制代码
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

@Data
public class User {
    private Long id;
    private String name;
    
    // 序列化格式:yyyy-MM-dd HH:mm:ss
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    
    @JsonFormat(pattern = "HH:mm:ss")
    private Date alarmTime;
}
相关推荐
hanyi_qwe17 小时前
MySQL事务基础
数据库·mysql
l1t17 小时前
三种用SQL解决Advent of Code 2022第8题 树顶木屋 的比较和分析
数据库·sql·oracle·duckdb·advent of code
如果未来,17 小时前
Oracle的Redo log和Undo log的区别
数据库·oracle
koping_wu17 小时前
【方案设计】Mysql相关场景
数据库·mysql
杨云龙UP17 小时前
SQL Server小技巧:用 SSMS 重置登录密码,不影响正在运行的系统
运维·服务器·数据库·sql·sqlserver
洁洁!17 小时前
openEuler多样性算力支持实践:容器化多架构应用部署与调度
服务器·数据库·科技·语言模型·数据分析
白露与泡影18 小时前
MySQL整体设计与存储引擎深度剖析:从架构哲学到引擎选型(了解)
数据库·mysql·架构
ManageEngine卓豪18 小时前
企业网站监控与性能优化指南
数据库·microsoft·性能优化
小小哭包18 小时前
Spring+MyBatis实现数据库读写分离方案
数据库·spring·mybatis