携带不符合正则的cardNumber请求未抛出ConstraintViolationException问题
字段正则校验未触发ConstraintViolationException的排查与解决
问题场景
- Postman请求示例:
apiName/v1/account?cardNumer=55^fields=customerName - 契约AccountApi中cardNumber的正则校验:
@Pattern(regexp = "^[0-9]{6}[A-Z][0-9]{9}$") @Parameter(name = "cardNumber") - 实现契约的AccountController(已加@Validated注解):
@RestController @Validated @Slf4j public class AccountController implements AccountApi { @Override public ResponseEntity<List<Account>> getAccount(String cardNumer) { // 业务逻辑实现 } } - 已配置的ConstraintViolationException异常处理器:
@ControllerAdvice public class AccountControllerExceptionHandler{ @ExceptionHandler(value = {ConstraintViolationException.class}) @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public Error manageErrorRegexViolation(final ConstraintViolationException e, HttpServletResponse response) { log.error("Error ConstraintViolationException {}.", e.getMessage()); // 未返回有效Error实例 } }
排查解决步骤
修正参数名拼写错误
请求参数写的是cardNumer(少了字母b),但契约注解里的参数名是cardNumber,Controller方法参数也用了cardNumer。参数名不匹配的话,校验注解根本找不到要校验的目标,自然不会触发异常。
解决:把请求参数、Controller方法参数统一改成cardNumber,和契约注解的name属性保持一致。确保接口注解能被继承识别
Spring MVC默认不会将接口方法参数上的校验注解继承到实现类。要么直接在Controller的getAccount方法参数上添加@Pattern注解,要么给接口AccountApi也加上@Validated注解,让Spring能扫描到接口上的校验规则。完善异常处理器的返回逻辑
当前异常处理器只做了日志打印,没有返回有效的Error对象实例。虽然这不会影响异常触发,但会导致前端拿不到正确的错误响应。补充返回逻辑,比如:public Error manageErrorRegexViolation(final ConstraintViolationException e, HttpServletResponse response) { log.error("Error ConstraintViolationException {}.", e.getMessage()); Error error = new Error(); error.setCode(HttpStatus.BAD_REQUEST.value()); error.setMessage(e.getMessage()); return error; }确认@Validated的生效范围
检查@Validated注解是否正确作用于需要校验的层级。如果是接口层面的校验,确保接口和实现类都正确配置了相关注解,让Spring的校验器能识别到参数上的校验规则。
内容的提问来源于stack exchange,提问作者Gregory Pellegrin
相关产品推荐
相关产品推荐

