如何让Spring返回Hibernate Validator自定义的简洁校验错误信息?
问题:如何简化Hibernate Validator校验后的错误响应,仅返回自定义提示信息?
我定义了DependentDto类,用@NotNull、@Pattern等Hibernate Validator注解设置了字段校验规则和自定义提示信息。用Postman测试接口时,字段不符合校验规则(比如dateOfBirth格式错误),返回的错误响应包含大量冗余内容,我只想返回自定义的提示信息,试过ValidationMessages.properties但没生效,该怎么实现?
相关代码
public class DependentDto { private UUID id; @JsonIgnoreProperties(value = {"dateOfBirth", "age", "maritalStatus", "bloodGroup", "religion", "aadharNumber", "panCardNumber", "uanNumber", "passportNumber", "permanentAddress", "communicationAddress", "guardianName","nextOfKin","nextOfKinContactNumber","skillSet","employeeDto"}) private PersonalInformationDto personalInformationDto; @NotNull(message = "Name can not be null") private String name; @NotNull(message = "Relation can not be null") private String relation; @NotNull(message = "Date Of Birth Date cannot be null") @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "Invalid date format. Please use the format yyyy-MM-dd (e.g., 2007-12-03).") private String dateOfBirth; @Pattern(regexp = "^\\+(?:[0-9] ?){6,14}[0-9]$", message = "Invalid phone number format") private String contactNumber; }
当前错误响应示例
{ "timestamp": "2024-01-23T10:32:04.470+00:00", "path": "/dependents", "status": 400, "error": "Bad Request", "message": "Validation failed for argument at index 0 in method: public reactor.core.publisher.Mono<com.frestonanalytics.msl.staffalyze.dto.DependentDto> com.frestonanalytics.msl.staffalyze.controller.DependentController.createDependent(com.frestonanalytics.msl.staffalyze.dto.DependentDto,org.springframework.web.server.ServerWebExchange), with 1 error(s): [Field error in object 'dependentDto' on field 'dateOfBirth': rejected value [1990-07-]; codes [Pattern.dependentDto.dateOfBirth,Pattern.dateOfBirth,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dependentDto.dateOfBirth,dateOfBirth]; arguments []; default message [dateOfBirth],[Ljavax.validation.constraints.Pattern$Flag;@b9d7349a,^\\d{4}-\\d{2}-\\d{2}$]; default message [Your custom error message for dateOfBirth pattern mismatch]] ", "requestId": "53206fd4-2", "errors": [ { "codes": [ "Pattern.dependentDto.dateOfBirth", "Pattern.dateOfBirth", "Pattern.java.lang.String", "Pattern" ], "arguments": [ { "codes": [ "dependentDto.dateOfBirth", "dateOfBirth" ], "arguments": null, "defaultMessage": "dateOfBirth", "code": "dateOfBirth" }, [], { "codes": [ "^\\d{4}-\\d{2}-\\d{2}$" ], "arguments": null, "defaultMessage": "^\\d{4}-\\d{2}-\\d{2}$" } ], "defaultMessage": "Your custom error message for dateOfBirth pattern mismatch", "objectName": "dependentDto", "field": "dateOfBirth", "rejectedValue": "1990-07-", "bindingFailure": false, "code": "Pattern" } ] }
解决方案
1. 自定义全局异常处理器(适配WebFlux环境)
从你的controller返回Mono可以看出项目使用Spring WebFlux,需要捕获WebExchangeBindException(WebFlux中校验失败抛出的异常),提取自定义提示信息并返回简化响应。
创建全局异常处理器类:
import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.support.WebExchangeBindException; import reactor.core.publisher.Mono; import java.util.List; import java.util.stream.Collectors; @ControllerAdvice public class ValidationExceptionHandler { @ExceptionHandler(WebExchangeBindException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Mono<List<String>> handleValidationErrors(WebExchangeBindException ex) { List<String> errorMessages = ex.getBindingResult().getAllErrors() .stream() .map(error -> error.getDefaultMessage()) .collect(Collectors.toList()); return Mono.just(errorMessages); } }
可选调整:返回单个错误信息
如果只需要返回第一条错误提示,修改返回逻辑:
@ExceptionHandler(WebExchangeBindException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Mono<String> handleSingleValidationError(WebExchangeBindException ex) { String firstError = ex.getBindingResult().getAllErrors().get(0).getDefaultMessage(); return Mono.just(firstError); }
2. 修复ValidationMessages.properties未生效问题
如果想用配置文件统一管理提示信息,按以下步骤调整:
- 修改Dto中的注解,使用占位符替代硬编码提示:
@NotNull(message = "{dependent.name.not.null}") private String name; @NotNull(message = "{dependent.relation.not.null}") private String relation; @NotNull(message = "{dependent.dateOfBirth.not.null}") @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}$", message = "{dependent.dateOfBirth.pattern}") private String dateOfBirth; @Pattern(regexp = "^\\+(?:[0-9] ?){6,14}[0-9]$", message = "{dependent.contactNumber.pattern}") private String contactNumber; - 在
src/main/resources下创建ValidationMessages.properties文件:dependent.name.not.null=Name can not be null dependent.relation.not.null=Relation can not be null dependent.dateOfBirth.not.null=Date Of Birth Date cannot be null dependent.dateOfBirth.pattern=Invalid date format. Please use the format yyyy-MM-dd (e.g., 2007-12-03). dependent.contactNumber.pattern=Invalid phone number format - 确保项目未自定义覆盖默认的MessageSource,WebFlux会自动加载该配置文件。
3. 最终效果
配置完成后,当dateOfBirth格式错误时,返回的响应会简化为:
["Invalid date format. Please use the format yyyy-MM-dd (e.g., 2007-12-03)."]
如果选择返回单个错误,响应为:
"Invalid date format. Please use the format yyyy-MM-dd (e.g., 2007-12-03)."
内容的提问来源于stack exchange,提问作者Ash
相关产品推荐
相关产品推荐

