简体   繁体   中英

ResponsEentityExceptionHandler: handleMethodArgumentNotValid Not Intercepted

My controller has the following method:

@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public void save(@RequestBody @Valid final User resource) {
    createInternal(resource);
}

Because of the @Valid before the resource parameter, I expect it to be intercepted by the following exception handler when I pass in a NULL into a nullable=false on my @Column of my entity,

@Override
protected final ResponseEntity<Object> handleMethodArgumentNotValid(final MethodArgumentNotValidException e,                                     
                                                                    final HttpHeaders headers, 
                                                                    final HttpStatus status, 
                                                                    final WebRequest request) {
    log.info("Bad Request: {}", ex.getMessage());
    log.debug("Bad Request: ", ex);

    ...

    return handleExceptionInternal(e, dto, headers, HttpStatus.BAD_REQUEST, request);
}

But it seems I can only handle it this way instead:

@ExceptionHandler(value = { ConstraintViolationException.class,  
                            DataIntegrityViolationException.class })
public final ResponseEntity<Object> handleBadRequest(final RuntimeException e,
                                                     final WebRequest request) {
    ...
    return handleExceptionInternal(ex, apiError, new HttpHeaders(), HttpStatus.BAD_REQUEST, request);
}

Why isn't the handleMethodArgumentNotValid exception handler picking it up like it should?

Before your 'handleMethodArgumentNotValid' has a chance to fire, DefaultHandlerExceptionResolver handles this

or if you want to handle declare , @ExceptionHandler(MethodArgumentNotValidException.class)

An @RequestBody method parameter can be annotated with @Valid, in which case it will be validated using the configured Validator instance. When using the MVC namespace or the MVC Java config, a JSR-303 validator is configured automatically assuming a JSR-303 implementation is available on the classpath.

Just like with @ModelAttribute parameters, an Errors argument can be used to examine the errors. If such an argument is not declared, a MethodArgumentNotValidException will be raised. The exception is handled in the DefaultHandlerExceptionResolver, which sends a 400 error back to the client. Before your 'handleMethodArgumentNotValid' has a chance to fire, this is handndf

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-requestbody

Why isn't the handleMethodArgumentNotValid exception handler picking it up like it should?

Spring container (during start up) scans through all of the controller(s) methods annotated with @RequestMapping and @ExceptionHandler .

Later, when the request comes with an url , the controller method will be identified using handlermapping , then injects all the required dependencies (controller method arguments) like Model , HttpRequest , etc.. and delegates the call the controller method to serve the input request.

Since your handleMethodArgumentNotValid is not annotated with either @RequestMapping or @ExceptionHandler , Spring container can't recognise this method.

@ExceptionHandler({ ConstraintViolationException.class })
public ResponseEntity<> handleConstraintViolation(ConstraintViolationException ex, 
    WebRequest request) {
    // error handeling

    return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
}

More details at https://www.baeldung.com/global-error-handler-in-a-spring-rest-api

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM