@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;
}
相关推荐
JIngJaneIL20 分钟前
基于springboot + vue房屋租赁管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
陈平安安1 小时前
设计一个秒杀功能
java·数据库·sql
isNotNullX1 小时前
数据处理的流程是什么?如何进行数据预处理?
数据库·数据资产管理·数据处理·企业数字化
TAEHENGV1 小时前
基本设置模块 Cordova 与 OpenHarmony 混合开发实战
android·java·数据库
Leo1871 小时前
MySQL 回表(Back to Table)详解
数据库·mysql
不知江月待何人..1 小时前
MySQL服务无法启动问题
数据库·mysql
廋到被风吹走1 小时前
【数据库】【Oracle】SQL基础
数据库·sql·oracle
曹牧1 小时前
Oracle统计每日发生次数
数据库·oracle
范纹杉想快点毕业2 小时前
返璞归真还是拥抱现代?——嵌入式研发中的“裸机开发”与RTOS全景解析
c语言·数据库·mongodb·设计模式·nosql
辗转.9532 小时前
MongoDB入门指南:从零开始掌握NoSQL数据库
数据库·mongodb·nosql