@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字段
}
典型应用场景
-
敏感信息:密码、token、密钥等
-
大对象:大文本、二进制数据、集合等
-
循环引用:避免toString死循环
-
冗余信息:不需要调试的字段
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. 最佳实践建议
-
安全性优先:
java
// 必须排除的字段 @ToString.Exclude private String password; @ToString.Exclude private String token; @ToString.Exclude private String privateKey;
-
性能考虑:
java
// 大字段排除 @ToString.Exclude private String largeText; @ToString.Exclude private byte[] fileContent; @ToString.Exclude private List<BigObject> bigList;
-
日志可读性:
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; } -
继承链处理:
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来保护敏感数据和保持日志简洁。

8953

被折叠的 条评论
为什么被折叠?



