Java中如何在BillsDto中隐藏关联UserDto的敏感字段?
解决BillsDto中隐藏关联UserDto敏感字段的方法(不修改UserDto)
以下是三种无需修改UserDto类即可实现需求的方案:
方法1:使用Jackson的@JsonFilter动态过滤字段
通过定义Jackson过滤器,可动态指定需要排除的敏感字段,无需改动原类代码。
- 为
BillsDto标记过滤器名称:
@JsonFilter("UserSensitiveFilter") public class BillsDto { private String numberBills; private double amount; private Date deadlinePayment; private UserDto user; // 省略getter/setter方法 }
- 配置ObjectMapper注册过滤器(以Spring Boot为例):
@Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); SimpleFilterProvider filterProvider = new SimpleFilterProvider(); // 对UserDto类型应用过滤器,排除指定敏感字段 filterProvider.addFilter("UserSensitiveFilter", SimpleBeanPropertyFilter.serializeAllExcept("username", "password", "age")); mapper.setFilterProvider(filterProvider); return mapper; }
序列化BillsDto时,关联的UserDto会自动排除指定的三个敏感字段。
方法2:自定义序列化器处理UserDto字段
为BillsDto中的user字段编写自定义序列化逻辑,只序列化需要展示的字段。
- 实现自定义序列化器:
public class UserSummarySerializer extends StdSerializer<UserDto> { public UserSummarySerializer() { this(null); } public UserSummarySerializer(Class<UserDto> t) { super(t); } @Override public void serialize(UserDto user, JsonGenerator gen, SerializerProvider provider) throws IOException { gen.writeStartObject(); // 仅序列化允许展示的字段 gen.writeStringField("number_id", user.getNumber_id()); gen.writeStringField("firstName", user.getFirstName()); gen.writeStringField("lastName", user.getLastName()); gen.writeEndObject(); } }
- 在
BillsDto的user字段上指定使用该序列化器:
public class BillsDto { private String numberBills; private double amount; private Date deadlinePayment; @JsonSerialize(using = UserSummarySerializer.class) private UserDto user; // 省略getter/setter方法 }
序列化时,user字段会按照自定义逻辑输出,自动隐藏敏感字段。
方法3:创建精简版DTO做转换
通过创建仅包含需展示字段的UserSummaryDto,在BillsDto中转换后返回,避免直接序列化原UserDto。
- 定义精简版用户DTO:
public class UserSummaryDto { private String number_id; private String firstName; private String lastName; // 从UserDto构造精简对象 public UserSummaryDto(UserDto user) { this.number_id = user.getNumber_id(); this.firstName = user.getFirstName(); this.lastName = user.getLastName(); } // 省略getter/setter方法 }
- 修改
BillsDto,隐藏原user字段并返回精简对象:
public class BillsDto { private String numberBills; private double amount; private Date deadlinePayment; @JsonIgnore // 隐藏原UserDto字段,不参与序列化 private UserDto user; // 序列化时返回精简版用户对象,对外仍以"user"字段展示 @JsonProperty("user") public UserSummaryDto getUserSummary() { return new UserSummaryDto(user); } // 保留原setter供业务逻辑赋值使用 public void setUser(UserDto user) { this.user = user; } // 省略其他字段的getter/setter方法 }
该方案逻辑清晰,能严格控制返回字段的范围,适合对接口输出有明确规范的场景。
内容的提问来源于stack exchange,提问作者Joaquim Oliveira
相关产品推荐
相关产品推荐

