Jackson中如何验证WRITE_ONLY未序列化字段的有效性?
解决@Valid与@JsonProperty(WRITE_ONLY)共存时验证不执行的问题
你遇到的问题是因为@JsonProperty(Access.WRITE_ONLY)虽能保证字段不被序列化到响应,但部分验证框架(比如Hibernate Validator)处理这类字段时,不会触发字段内部的@Valid验证逻辑。以下是几种可行的解决办法:
方法一:使用@JsonView拆分序列化/反序列化视图
定义两个视图接口,分别对应请求(反序列化)和响应(序列化)场景:
// 用于请求反序列化的视图 public interface RequestView {} // 用于响应序列化的视图 public interface ResponseView {}
在DTO的字段上配置对应视图:
public class YourRequestDTO { @Valid @JsonView(RequestView.class) private User user; // 其他需要返回的响应字段 @JsonView(ResponseView.class) private String otherField; }
最后在Controller方法上指定视图:
@PostMapping("/your-api") @JsonView(ResponseView.class) public ResponseEntity<YourRequestDTO> handleRequest( @RequestBody @JsonView(RequestView.class) @Valid YourRequestDTO dto) { // 业务逻辑处理 return ResponseEntity.ok(dto); }
这种方式既保证user字段在请求时被解析并验证,又不会出现在响应结果中。
方法二:将@Valid移至构造方法参数
利用Jackson反序列化时调用构造方法的特性,把@Valid标注在构造方法参数上,同时保留字段的WRITE_ONLY配置:
public class YourRequestDTO { @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private User user; // 带参构造方法,参数添加@Valid public YourRequestDTO(@Valid User user) { this.user = user; } // 无参构造方法(Jackson反序列化必需) public YourRequestDTO() {} }
反序列化时,构造方法参数的@Valid会触发对User对象的验证,字段依然保持WRITE_ONLY不会出现在响应里。
方法三:在Setter方法上添加@Valid
如果DTO使用Setter注入字段,可把@Valid移到Setter方法上:
public class YourRequestDTO { @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) private User user; @Valid public void setUser(User user) { this.user = user; } }
Jackson反序列化调用Setter时,会触发@Valid的验证逻辑,字段的WRITE_ONLY属性确保它不会被序列化到响应。
内容的提问来源于stack exchange,提问作者Yuval
相关产品推荐
相关产品推荐

