父DTO返回时如何自动携带包含所有空字段的完整子DTO
嗨,我完全懂你的困扰——你希望创建父DTO(Student)时,哪怕没手动设置子DTO(School),它也能自动生成一个带所有空字段的完整School对象,而不是直接返回null。这个问题核心出在Builder模式的初始化逻辑上,我给你两种实用的解决思路:
1. 手动修改Builder的初始化逻辑
如果是你自己手写的Builder类,可以在Student的构造方法或者Builder的build方法里,给school字段设置默认的空School对象。这样就算不调用.school()方法,school也不会是null,而是一个所有字段都为null的School实例。
修改后的Student类代码示例:
public class Student { private String name; private School school; // 私有构造方法,仅由Builder调用 private Student(Builder builder) { this.name = builder.name; // 关键逻辑:如果builder中的school为null,就创建空的School对象 this.school = builder.school != null ? builder.school : School.builder().build(); } public static Builder builder() { return new Builder(); } public static class Builder { private String name; private School school; public Builder name(String name) { this.name = name; return this; } public Builder school(School school) { this.school = school; return this; } public Student build() { return new Student(this); } } }
现在调用Student.builder().build()时,school会自动初始化为School.builder().build(),序列化后就能得到你想要的{name:null , school: {schoolName: null, address: null}}结构。
2. 用Lombok简化配置(如果项目用Lombok的话)
要是你用Lombok的@Builder注解自动生成Builder,只需要给school字段加上@Builder.Default注解,指定默认值为一个空的School对象就行:
import lombok.Builder; import lombok.Data; @Data @Builder public class Student { private String name; // 给school设置默认的空School对象 @Builder.Default private School school = School.builder().build(); } @Data @Builder public class School { private String schoolName; private String address; }
Lombok会自动帮你处理Builder的默认值逻辑,不用手动写构造和Builder代码,省心又高效。
为什么原来的代码会返回school:null?
因为你原来的Student Builder初始化时,school字段默认是null,没有给它分配School实例。当你不手动调用.school(School.builder().build())时,这个属性就保持null状态,序列化后自然显示为school:null。而上面的两种方法,都是确保school在任何情况下都会是一个School对象——哪怕它的所有字段都是null,这样序列化后就能输出完整的结构了。
备注:内容来源于stack exchange,提问作者JAYESH rathi

