如何在自定义Jakarta Bean Validation中定位校验失败的字段?
解决UUID校验失败时返回具体字段名的问题
要让校验器返回具体的失败字段,核心是在**全局异常处理器(GlobalExceptionHandler)**中从MethodArgumentNotValidException里提取字段信息,具体步骤如下:
1. 修改全局异常处理器
在处理MethodArgumentNotValidException的方法中,通过BindingResult获取FieldError,从中提取校验失败的字段名,并将其加入返回的错误详情中:
@ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<ErrorResponse> handleValidationErrors(MethodArgumentNotValidException ex) { ErrorResponse errorResp = new ErrorResponse(); errorResp.setException(ex.getClass().getName()); errorResp.setTimeStamp(System.currentTimeMillis()); List<ErrorDetail> errorDetails = new ArrayList<>(); // 遍历所有字段校验错误 ex.getBindingResult().getFieldErrors().forEach(fieldError -> { ErrorDetail detail = new ErrorDetail(); detail.setKey(fieldError.getCode()); detail.setMessage(fieldError.getDefaultMessage()); detail.setField(fieldError.getField()); // 添加校验失败的字段名 // 原有属性赋值(errorCode、args) errorDetails.add(detail); }); errorResp.setErrorDetail(errorDetails); return new ResponseEntity<>(errorResp, HttpStatus.BAD_REQUEST); }
2. 更新错误详情类(ErrorDetail)
如果你的ErrorDetail类没有存储字段名的属性,需要添加对应的字段及getter/setter:
@Data public class ErrorDetail { private String key; private String message; private String errorCode; private Object[] args; private String field; // 新增:存储校验失败的字段名 }
3. 可选:优化错误提示(可选)
如果想在错误消息中直接包含字段名,可以修改@UUID注解的默认message,结合Hibernate Validator的占位符:
public @interface UUID { // 用占位符获取字段名 String message() default "{invalid.uuid,field=${validatedValue.field}}"; // 其他属性不变 Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
然后在国际化配置文件(如messages.properties)中定义消息模板:
invalid.uuid=Invalid UUID for field: {field}
完成修改后,返回的错误信息会包含具体字段名,示例返回如下:
{ "exception": "org.springframework.web.bind.MethodArgumentNotValidException", "timeStamp": 1676468004793, "errorDetail": [ { "key": "invalid.uuid", "message": "Invalid UUID", "errorCode": null, "args": null, "field": "gitlabId" } ] }
内容的提问来源于stack exchange,提问作者erondem
相关产品推荐
相关产品推荐

