lombok中的@ToString.Exclude和@ToString.Include控制日志输出

@ToString.Exclude@ToString.Include是Lombok的@ToString注解的配置项,用于精细控制哪些字段出现在toString()方法中。它们的作用和区别如下:

1. @ToString.Exclude(排除字段)

作用

从toString()方法中排除指定的字段

使用场景

java

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class User {
    private Long id;
    private String username;
    
    @ToString.Exclude  // 不希望在日志中泄露密码
    private String password;
    
    private String email;
    
    @ToString.Exclude  // 大对象,避免toString过长
    private byte[] avatar;
}

生成的toString()

java

public String toString() {
    return "User(id=" + this.id + 
           ", username=" + this.username + 
           ", email=" + this.email + ")";
    // 没有password和avatar字段
}

典型应用场景

  1. 敏感信息:密码、token、密钥等

  2. 大对象:大文本、二进制数据、集合等

  3. 循环引用:避免toString死循环

  4. 冗余信息:不需要调试的字段

2. @ToString.Include(包含字段)

作用

配合onlyExplicitlyIncluded = true使用,只包含指定的字段

使用场景

java

import lombok.Data;
import lombok.ToString;

@Data
@ToString(onlyExplicitlyIncluded = true)  // 只包含标记的字段
public class User {
    @ToString.Include  // 明确标记要包含的字段
    private Long id;
    
    @ToString.Include
    private String username;
    
    private String password;  // 不会被包含
    
    private String email;     // 不会被包含
}

生成的toString()

java

public String toString() {
    return "User(id=" + this.id + ", username=" + this.username + ")";
    // 只包含id和username
}

3. 两者区别对比

特性@ToString.Exclude@ToString.Include
默认行为排除指定字段不包含任何字段(除非标记)
使用前提默认包含所有字段必须设置onlyExplicitlyIncluded = true
适用场景排除少数敏感字段只显示少数关键字段
代码意图"除了这些,我都要""我只想要这些"
使用频率常用较少用

4. 实际应用示例

示例1:财务DTO排除敏感字段

java

@Data
@ToString(callSuper = true)
public class PaymentDTO extends BasePageQuery {
    private String paymentNo;
    private BigDecimal amount;
    
    @ToString.Exclude  // 排除银行卡号
    private String bankCardNo;
    
    @ToString.Exclude  // 排除CVV安全码
    private String cvv;
    
    @ToString.Exclude  // 排除支付令牌
    private String paymentToken;
    
    private String status;
    private Date createTime;
}

示例2:用户DTO只显示关键字段

java

@Data
@ToString(onlyExplicitlyIncluded = true)
public class UserSimpleDTO {
    @ToString.Include
    private Long id;
    
    @ToString.Include
    private String username;
    
    @ToString.Include(name = "昵称")  // 自定义字段名
    private String nickname;
    
    private String password;
    private String email;
    private String phone;
    private String address;
}
// 输出:UserSimpleDTO(id=1, username=张三, 昵称=三哥)

示例3:结合使用(更复杂的场景)

java

@Data
@ToString(callSuper = true, onlyExplicitlyIncluded = true)
public class CapitalInfoQueryDTO extends BasePageQuery {
    @ToString.Include
    private String capitalNo;
    
    @ToString.Include
    private String capitalName;
    
    @ToString.Include(rank = 1)  // 排序优先级
    private Integer capitalYear;
    
    @ToString.Include
    private Integer capitalState;
    
    // 以下字段不会出现在toString中
    private String capitalAccount;
    private String capitalSource;
    
    @ToString.Exclude  // 即使标记了Include,Exclude优先级更高
    private String remark;  
    
    @ToString.Exclude
    private List<String> createDateRange;
}

5. 高级用法

rank属性(排序控制)

java

@Data
@ToString
public class Product {
    @ToString.Include(rank = 1)  // 最高优先级,最先显示
    private Long id;
    
    @ToString.Include(rank = 2)
    private String name;
    
    private String description;  // 默认rank=0
    
    @ToString.Include(rank = 10)  // 低优先级,最后显示
    private Date createTime;
}
// 输出:Product(id=1, name=手机, description=xxx, createTime=2024-01-01)

name属性(自定义字段名)

java

@Data
@ToString
public class Order {
    @ToString.Include(name = "订单号")
    private String orderNo;
    
    @ToString.Include(name = "总金额")
    private BigDecimal totalAmount;
}
// 输出:Order(订单号=20240101001, 总金额=199.00)

在方法上使用

java

@Data
@ToString
public class User {
    private String firstName;
    private String lastName;
    
    @ToString.Include(name = "全名")
    public String getFullName() {
        return firstName + " " + lastName;
    }
}
// 输出:User(firstName=张, lastName=三, 全名=张 三)

6. 在您的CapitalInfoQueryDTO中的应用建议

方案A:排除敏感和大字段(推荐)

java

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class CapitalInfoQueryDTO extends BasePageQuery {
    private String capitalNo;
    private String capitalName;
    private String capitalType;
    
    @ToString.Exclude  // 敏感信息,不在日志中显示
    private String capitalAccount;
    
    @ToString.Exclude  // 大字段,避免日志过长
    private String remark;
    
    @ToString.Exclude  // 集合字段,避免日志过长
    private List<String> createDateRange;
    
    // 其他字段...
}

方案B:只显示关键字段

java

@Data
@ToString(callSuper = true, onlyExplicitlyIncluded = true)
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class CapitalInfoQueryDTO extends BasePageQuery {
    @ToString.Include
    private String capitalNo;
    
    @ToString.Include
    private String capitalName;
    
    @ToString.Include
    private String capitalType;
    
    @ToString.Include
    private Integer capitalYear;
    
    // 以下字段不会出现在toString中
    private String capitalAccount;
    private String remark;
    private List<String> createDateRange;
    // 其他字段...
}

方案C:开发和生产环境不同配置

java

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class CapitalInfoQueryDTO extends BasePageQuery {
    private String capitalNo;
    private String capitalName;
    
    // 开发环境显示,生产环境隐藏
    @ToString.Exclude(ifToString = "!${debug:false}")
    private String debugInfo;
    
    // 生产环境始终隐藏
    @ToString.Exclude
    private String sensitiveInfo;
}

7. 最佳实践建议

  1. 安全性优先

    java

    // 必须排除的字段
    @ToString.Exclude
    private String password;
    @ToString.Exclude
    private String token;
    @ToString.Exclude
    private String privateKey;
  2. 性能考虑

    java

    // 大字段排除
    @ToString.Exclude
    private String largeText;
    @ToString.Exclude
    private byte[] fileContent;
    @ToString.Exclude
    private List<BigObject> bigList;
  3. 日志可读性

    java

    // 只保留关键字段
    @ToString(callSuper = true)
    public class QueryDTO {
        @ToString.Include(name = "ID")
        private Long id;
        
        @ToString.Include(name = "名称")
        private String name;
        
        @ToString.Exclude
        private String unnecessaryField;
    }
  4. 继承链处理

    java

    @Data
    @ToString(callSuper = true)  // 包含父类字段
    public class ChildDTO extends ParentDTO {
        @ToString.Exclude
        private String childSensitiveField;
    }

总结

  • 使用@ToString.Exclude:当你想从默认包含所有字段的情况下排除特定字段时

  • 使用@ToString.Include:当你只想显示少数重要字段时(需配合onlyExplicitlyIncluded = true

  • 选择标准

    • 大部分情况用@ToString.Exclude排除敏感字段

    • 如果字段太多,用onlyExplicitlyIncluded = true只包含关键字段

    • 始终考虑安全性和日志可读性

对于您的CapitalInfoQueryDTO,考虑到可能有敏感信息(如账户信息)和大字段(如备注、日期范围),建议使用@ToString.Exclude来保护敏感数据和保持日志简洁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值