Extend RepositoryRestExceptionHandler

2020-07-30 08:58发布

问题:

I want to extend RepositoryRestExceptionHandler to handle errors in my RestController.

I have Validators and working great when using RestRepository but when i use RestController they are not so i did manual Validation like below

Errors errors = new BeanPropertyBindingResult(NumberRange, "range");
    NumberRangeValidator.validate(NumberRange, errors);

    if(errors.hasErrors()) {
         throw new RepositoryConstraintViolationException(errors);
    }

this is resulting in error 500 , what i want to have as result is same as 400 bad request with errors listed in the body .

i think i should have to extend the below class to handle exception from my rest controller

@ControllerAdvice(basePackageClasses = RepositoryRestExceptionHandler.class)
public class RepositoryRestExceptionHandler { .... }

I am trying to avoid creating ControllerAdvice exactly the same as RepositoryRestExceptionHandler

thanks

回答1:

The RepositoryRestExceptionHandler is restricted to controllers from its own package - this basically means that it is just applied when the spring data rest controller (RepositoryEntityController) is invoked.

So I would just try to extend RepositoryRestExceptionHandler and annotate your subclass with a package that includes the controllers it should apply to :

@ControllerAdvice(basePackages="com.my.package")

This way you will not change the exception handling behaviour of spring data rest and make sure you just enhance the error handling of your controller methods.

I just tried this - so my custom controller (annotated with @RepositoryRestController) contains a method that throws a RepositoryConstraintViolationException. The spring data rest exception handler RepositoryRestExceptionHandler converts this exception into a BAD_REQUEST (400).

But this is not applied in my custom controller method - I get a INTERNAL_SERVER_ERROR (500).

So I extend the RepositoryRestExceptionHandler and annotate my controller advice so it only applies to the packages of my controller:

@ControllerAdvice(basePackageClasses = DefaultExceptionHandler.class)
public class DefaultExceptionHandler extends RepositoryRestExceptionHandler {

    @Autowired
    public DefaultExceptionHandler(MessageSource messageSource) {
        super(messageSource);
    }
}

With this ControllerAdvice in place I receive a BAD_REQUEST 400 - so this works as expected.