Spring控制器中的异常处理

图片



实际上,通常需要集中处理控制器甚至整个应用程序中的异常。在本文中,我们将分析Spring框架提供的解决此问题的主要功能,并通过简单的示例,让我们了解一切的工作原理。谁对此主题感兴趣-欢迎参加!



最初,在Spring 3.2之前处理应用程序中异常主要方法是HandlerExceptionResolver@ExceptionHandler注解我们将在下面更详细地分析它们,但是它们具有某些缺点。从3.2版开始,出现@ControllerAdvice批注,该批注消除了先前解决方案限制。春季5中,添加了一个新的ResponseStatusException类,该类对于处理REST API的基本错误非常方便



现在,首先要开始!



控制器异常处理-@ExceptionHandler



@ExceptionHandler . , , .



:



@RestController
public class Example1Controller {

    @GetMapping(value = "/testExceptionHandler", produces = APPLICATION_JSON_VALUE)
    public Response testExceptionHandler(@RequestParam(required = false, defaultValue = "false") boolean exception)
            throws BusinessException {
        if (exception) {
            throw new BusinessException("BusinessException in testExceptionHandler");
        }
        return new Response("OK");
    }

    @ExceptionHandler(BusinessException.class)
    public Response handleException(BusinessException e) {
        return new Response(e.getMessage());
    }

}


testExceptionHandler, BusinessException, — . , , .



handleException . @ExceptionHandler(BusinessException.class), BusinessException. @ExceptionHandler , : @ExceptionHandler({BusinessException.class, ServiceException.class}).



— 200 JSON . , @ResponseStatus, @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR).



:





:





@ExceptionHandler , . @ExceptionHandler , , , .



HandlerExceptionResolver



HandlerExceptionResolver Spring. HandlerExceptionResolver. , , Spring . :



ExceptionHandlerExceptionResolver @ExceptionHandler, .



DefaultHandlerExceptionResolver — Spring , :



Exception HTTP Status Code
BindException 400 (Bad Request)
ConversionNotSupportedException 500 (Internal Server Error)
HttpMediaTypeNotAcceptableException 406 (Not Acceptable)
HttpMediaTypeNotSupportedException 415 (Unsupported Media Type)
HttpMessageNotReadableException 400 (Bad Request)
HttpMessageNotWritableException 500 (Internal Server Error)
HttpRequestMethodNotSupportedException 405 (Method Not Allowed)
MethodArgumentNotValidException 400 (Bad Request)
MissingServletRequestParameterException 400 (Bad Request)
MissingServletRequestPartException 400 (Bad Request)
NoSuchRequestHandlingMethodException 404 (Not Found)
TypeMismatchException 400 (Bad Request)


, REST API . . ModelAndView, , .



ResponseStatusExceptionResolver @ResponseStatus.



ServiceException:



@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public class ServiceException extends Exception {

    public ServiceException(String message) {
        super(message);
    }

}


ServiceException @ResponseStatus value INTERNAL_SERVER_ERROR, - 500.



:



@RestController
public class Example2Controller {

    @GetMapping(value = "/testResponseStatusExceptionResolver", produces = APPLICATION_JSON_VALUE)
    public Response testResponseStatusExceptionResolver(@RequestParam(required = false, defaultValue = "false") boolean exception)
            throws ServiceException {
        if (exception) {
            throw new ServiceException("ServiceException in testResponseStatusExceptionResolver");
        }
        return new Response("OK");
    }

}


GET- exception=true, 500- :





— . , @ResponseStatus .



HandlerExceptionResolver , - JSON XML . , .



:



@Component
public class CustomExceptionResolver extends AbstractHandlerExceptionResolver {

    @Override
    protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
        if (ex instanceof CustomException) {
            modelAndView.setStatus(HttpStatus.BAD_REQUEST);
            modelAndView.addObject("message", "CustomException was handled");
            return modelAndView;

        }
        modelAndView.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
        modelAndView.addObject("message", "Another exception was handled");
        return modelAndView;
    }

}


, . , : , ModelAndView. JSON, .



-, . . , . , — :



@RestController
public class Example3Controller {

    @GetMapping(value = "/testCustomExceptionResolver", produces = APPLICATION_JSON_VALUE)
    public Response testCustomExceptionResolver(@RequestParam(required = false, defaultValue = "false") boolean exception)
            throws CustomException {
        if (exception) {
            throw new CustomException("CustomException in testCustomExceptionResolver");
        }
        return new Response("OK");
    }

}


:





200 JSON .



@ControllerAdvice



— . Spring 3.2 @ControllerAdvice.



:



@ControllerAdvice
public class DefaultAdvice {

    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<Response> handleException(BusinessException e) {
        Response response = new Response(e.getMessage());
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

}


, @ControllerAdvice , .

DefaultAdvice handleException. handleException @ExceptionHandler, , , . BusinessException.



: @ExceptionHandler({BusinessException.class, ServiceException.class}). @ExceptionHandler .

, handleException ResponseEntity Response:



public class Response {

    private String message;

    public Response() {
    }

    public Response(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}


, JSON . message HttpStatus.OK, 200.



:



@RestController
public class Example4Controller {

    @GetMapping(value = "/testDefaultControllerAdvice", produces = APPLICATION_JSON_VALUE)
    public Response testDefaultControllerAdvice(@RequestParam(required = false, defaultValue = "false") boolean exception)
            throws BusinessException {
        if (exception) {
            throw new BusinessException("BusinessException in testDefaultControllerAdvice");
        }
        return new Response("OK");
    }

}


, , JSON 200:





?

! :



@ControllerAdvice(annotations = CustomExceptionHandler.class)
public class CustomAdvice {

    @ExceptionHandler(BusinessException.class)
    public ResponseEntity<Response> handleException(BusinessException e) {
        String message = String.format("%s %s", LocalDateTime.now(), e.getMessage());
        Response response = new Response(message);
        return new ResponseEntity<>(response, HttpStatus.OK);
    }

}


@ControllerAdvice(annotations = CustomExceptionHandler.class). CustomAdvice , @CustomExceptionHandler.



@CustomExceptionHandler :



@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomExceptionHandler {
}


:



@RestController
@CustomExceptionHandler
public class Example5Controller {

    @GetMapping(value = "/testCustomControllerAdvice", produces = APPLICATION_JSON_VALUE)
    public Response testCustomControllerAdvice(@RequestParam(required = false, defaultValue = "false") boolean exception)
            throws BusinessException {
        if (exception) {
            throw new BusinessException("BusinessException in testCustomControllerAdvice");
        }
        return new Response("OK");
    }

}


Example5Controller @CustomExceptionHandler, Example4Controller . BusinessException CustomAdvice, DefaultAdvice, .



CustomAdvice — :





. @ControllerAdvice, . .



ResponseStatusException.



ResponseStatusException:



@RestController
public class Example6Controller {

    @GetMapping(value = "/testResponseStatusException", produces = APPLICATION_JSON_VALUE)
    public Response testResponseStatusException(@RequestParam(required = false, defaultValue = "false") boolean exception) {
        if (exception) {
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "ResponseStatusException in testResponseStatusException");
        }
        return new Response("OK");
    }

}


ResponseStatusException , , . @ResponseStatus — -. , .



:





简介:我们已经看到了处理异常的不同方法,每种方法都有其自身的特征。在大型应用程序中,您可以一次找到几种方法,但是您需要非常小心,并且不要使错误处理逻辑过于复杂。否则,将会发现某些异常将在错误的处理程序中处理,并且响应将不同于预期的响应。例如,如果应用程序有多个顾问程序,则在创建新顾问程序时,您需要确保它不会破坏处理旧控制器异常的现有顺序。

所以要小心,一切都会很好!



链接到文章的来源




All Articles