使用Lombok @SuperBuilder时布尔字段isInvoiced名称被修改的原因及解决方案咨询
Lombok @SuperBuilder时布尔字段isInvoiced名称被修改的原因及解决方案咨询
嘿,这个问题其实和JavaBean的命名规范、Lombok的处理逻辑,还有JSON序列化的规则都有关系,我来帮你拆解清楚:
问题根源
- JavaBean布尔字段的命名规范:按照JavaBean的标准,对于以
is开头的布尔类型字段(比如isInvoiced),对应的getter方法应该是isInvoiced(),而不是getIsInvoiced()。Lombok在生成Builder的时候会遵循这个规范生成设置方法;同时你的JSON序列化框架(比如Jackson)也会根据getter方法名推断JSON字段名,它会自动去掉is前缀,把字段名解析为invoiced,这就是为什么你看到JSON里是"invoiced": false而非预期的"isInvoiced"。 - OpenAPI显示双字段的原因:SmallRye OpenAPI在生成Schema时,可能同时读取了原字段名
isInvoiced和通过getter方法推断出来的invoiced,所以才会出现两个字段并存的情况。
解决方案
下面给你几个可行的解决办法,你可以根据需求选择:
方案1:调整字段命名(推荐)
直接遵循JavaBean规范,把字段名开头的is去掉,改成invoiced。这样Lombok生成的Builder方法、getter方法,还有JSON序列化的字段名都会保持一致,从根源上避免歧义:
@SuperBuilder @Getter @NoArgsConstructor public class ExpenseDto { @NonNull @Size(max = 30) protected String recipient; @NonNull @Size(max = 30) protected String purpose; // ... protected boolean invoiced; // 去掉is前缀,符合JavaBean规范 }
对应的Builder调用也需要同步调整:
public ExpenseEntityDto domainToEntityDto(Expense domain) { return ExpenseEntityDto.builder() .expenseId(domain.getExpenseId()) .accountNo(domain.getAccountNo()) .recipient(domain.getRecipient()) .purpose(domain.getPurpose()) .invoiced(domain.isInvoiced()) // 对应修改后的字段名 .build(); }
这样JSON输出就会是"invoiced": false,OpenAPI Schema也只会显示一个invoiced字段。
方案2:用注解强制指定JSON字段名(不修改字段名的情况)
如果你不想改动原字段名,可以给isInvoiced字段加上@JsonProperty注解,强制指定JSON序列化的字段名称,同时确保Lombok的Builder行为符合预期:
@SuperBuilder @Getter @NoArgsConstructor public class ExpenseDto { @NonNull @Size(max = 30) protected String recipient; @NonNull @Size(max = 30) protected String purpose; // ... @JsonProperty("isInvoiced") // 强制指定JSON输出的字段名 protected boolean isInvoiced; }
这样JSON序列化的时候会输出"isInvoiced": false,同时OpenAPI Schema也只会显示isInvoiced字段,不会再出现重复的invoiced。另外,Builder的调用代码不需要改动,依然可以用.isInvoiced(domain.isInvoiced())。
额外注意点
子类ExpenseEntityDto上的@Data注解会自动生成getter/setter,对于继承来的isInvoiced字段,它生成的getter还是isInvoiced(),所以上面的解决方案同样适用于子类场景,不需要额外调整子类代码。
备注:内容来源于stack exchange,提问作者onouv
相关产品推荐
相关产品推荐

