exception handling for filter in spring

后端 未结 7 871
既然无缘
既然无缘 2020-12-17 14:59

I am handling exceptions in spring using @ExceptionHandler. Any exception thrown by controller is caught using method annotated with @ExceptionHandler and action is taken ac

7条回答
  •  一整个雨季
    2020-12-17 15:53

    If, like me, you're stuck with spring 3.1 (just 0.1 vesrsions behind @ControllerAdvice) you can try this solution I just came up with.


    So, you've heard of exception resolvers, right? If not, read here:

    @Component
    public class RestExceptionResolver extends ExceptionHandlerExceptionResolver {
    
        @Autowired
        //If you have multiple handlers make this a list of handlers
        private RestExceptionHandler restExceptionHandler;
        /**
         * This resolver needs to be injected because it is the easiest (maybe only) way of getting the configured MessageConverters
         */
        @Resource
        private ExceptionHandlerExceptionResolver defaultResolver;
    
        @PostConstruct
        public void afterPropertiesSet() {
            setMessageConverters(defaultResolver.getMessageConverters());
            setOrder(2); // The annotation @Order(2) does not work for this type of component
            super.afterPropertiesSet();
        }
    
        @Override
        protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
            ExceptionHandlerMethodResolver methodResolver = new ExceptionHandlerMethodResolver(restExceptionHandler.getClass());
            Method method = methodResolver.resolveMethod(exception);
            if (method != null) {
                return new ServletInvocableHandlerMethod(restExceptionHandler, method);
            }
            return null;
        }
    
        public void setRestExceptionHandler(RestExceptionHandler restExceptionHandler) {
            this.restExceptionHandler = restExceptionHandler;
        }
    
        public void setDefaultResolver(ExceptionHandlerExceptionResolver defaultResolver) {
            this.defaultResolver = defaultResolver;
        }
    }
    

    Then an example handler will look like this

    @Component
    public class RestExceptionHandler {
    
        @ExceptionHandler(ResourceNotFoundException.class)
        @ResponseStatus(HttpStatus.NOT_FOUND)
        @ResponseBody
        public Map handleException(ResourceNotFoundException e, HttpServletResponse response) {
            Map error = new HashMap<>();
            error.put("error", e.getMessage());
            error.put("resource", e.getResource());
            return error;
        }
     }
    

    Of course you will not forget to register your beens


    Then create a filter that is called before your desiered filter (optionally all of 'em)

    Then in that filter

    try{
       chain.doFilter(request, response);
    catch(Exception e){
       exceptionResolver(request, response, exceptionHandler, e);
       //Make the processing stop here... 
       return; //just in case
    }
    

提交回复
热议问题