【发布时间】:2018-11-02 08:36:32
【问题描述】:
我有一个简单的@RestController。我的最终目标是能够验证传入的@QueryParam String id 是否为UUID。这部分有效,但IsValidUUIDValidator 引发的异常永远不会通过我的自定义ResponseEntityExceptionHandler。我需要它来控制错误的输出。
我已经阅读并尝试了一系列教程和博客,但无论我做什么验证异常都不会输入GlobalExceptionHandler#handleMethodArgumentNotValid。
为什么在我的自定义ResponseEntityExceptionHandler 中,验证异常从不通过handleMethodArgumentValid?
注意!我确实看到 Spring 从该类的默认构造函数中的一个简单日志事件中获取 GlobalExceptionHandler。
搜索资源
@RestController
@Path("/search")
public class SearchResource extends AbstractResource {
@GET
@Path("/suggestions")
@Produces(MediaType.APPLICATION_XML)
public Response getSuggestions(@IsValidUUID @QueryParam("territoryId") String territoryId) {
IsValidUUID
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {IsValidUUIDValidator.class})
public @interface IsValidUUID {
String message() default "Invalid UUID";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
isValidUUIDValidator
public class IsValidUUIDValidator implements ConstraintValidator<IsValidUUID, String> {
@Override
public void initialize(IsValidUUID constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null) {
return false;
}
try {
UUID.fromString(value);
return true;
} catch (Exception e) {
System.out.println("Invalid!");
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("The provided UUID is not valid")
.addConstraintViolation();
return false;
}
}
}
GlobalExceptionHandler
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
System.out.println("This method never gets invoked");
return super.handleMethodArgumentNotValid(ex, headers, status, request); //To change body of generated methods, choose Tools | Templates.
}
}
【问题讨论】:
-
尝试在
GlobalExceptionHandler下方的@Override下添加@ExceptionHandler( MethodArgumentNotValidException .class),如果不起作用,可以尝试将handleMethodArgumentNotValid从protected更改为public -
@rdj7 尝试将
protected更改为public,但没有成功。添加@ExceptionHandler会使Spring 抱怨MethodArgumentNotValidException的两个异常处理程序,因为ResponseEntityExceptionHandler在handleException中已经有一个用于此异常的@ExceptionHandler。
标签: validation spring-boot spring-4