我有一个春天@RestController
其 POST 端点定义如下:
@RestController
@Validated
@RequestMapping("/example")
public class Controller {
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<?> create(@Valid @RequestBody Request request,
BindingResult _unused, // DO NOT DELETE
UriComponentsBuilder uriBuilder) {
// ...
}
}
它还有一个异常处理程序javax.validation.ConstraintViolationException
:
@ExceptionHandler({ConstraintViolationException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
ProblemDetails handleValidationError(ConstraintViolationException e) {...}
我们的 Spring-Boot 应用程序正在使用spring-boot-starter-validation
用于验证。这Request
对象用途javax.validation.*
注释将约束应用于各个字段,如下所示:
public class Request {
private Long id;
@Size(max = 64, message = "name length cannot exceed 64 characters")
private String name;
// ...
}
如上所述,如果您使用无效请求 POST 请求,验证将抛出 ConstraintViolationException,该异常将由异常处理程序处理。这有效,我们对其进行了单元测试,一切都很好。
我注意到BindingResult
在 post 方法中没有使用(名称_unused
并评论//DO NOT DELETE
有点危险信号。)我继续删除了参数。突然间,我的测试失败了——入站请求仍然经过验证,但它不再抛出 ConstraintValidationException ...现在它抛出MethodArgumentNotValidException
!不幸的是,我无法使用这个其他异常,因为它不包含我需要的格式的失败验证(也不包含我需要的所有数据)。
为什么BindingResult
参数列表中的存在控制抛出哪个异常?如何删除未使用的变量并仍然抛出ConstraintViolationException
javax.validation何时判断请求体无效?
Spring-Boot 2.5.5
- spring-boot-启动器-web
- spring-boot-starter-验证
OpenJDK 17。