Spring MVC uniformly handled three ways

Body

Spring unified exception handling has three methods, namely:

  1. Using @ ExceptionHandler annotation
  2. Implementing the HandlerExceptionResolver interface
  3. Using @ Controlleradvice annotation

Using @ ExceptionHandler annotation

There is a downside to using this annotation: exception handling The method must be in the same Controller as the error method. Use it as follows:

copy code
 1 @Controller

2 public class GlobalController {
3
4 /**
5 * Used to handle exceptions
6 * @return
7 */
8 @ExceptionHandler({MyException.class})
9 public String exception(MyException e) {
10 System.out.println(e.getMessage());
11 e.printStackTrace();
12 return "exception";
13}
14
15 @RequestMapping("test")
16 public void test() {
17 throw new MyException("Something went wrong!");
18}
19}
copy code

It can be seen that the biggest drawback of this method is that it cannot control the exception globally. Each class must be written again.

Back to the top

Implement the HandlerExceptionResolver interface

This method allows global exception control. For example:

copy code
 1 @Component

2 public class ExceptionTest implements HandlerExceptionResolver{
3
4 /**
5 * TODO briefly describes the realization function of this method (optional).
6 * @see org.springframework.web.servlet.HandlerExceptionResolver#resolveException(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
7 */
8 public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
9 Exception ex) {
10 System.out.println("This is exception handler method!");
11 return null;
12}
13}
copy code

Back to top

Use @ControllerAdvice+ @ ExceptionHandler annotation

As mentioned above, @ ExceptionHandler needs to perform exception handling methods must be in the same Controller as the error method. Then when the code is added @ControllerAdvice, it does not need to be in the same controller. This is also a new feature brought by Spring 3.2. It can be seen from the name that it basically means controller enhancement. In other words, @controlleradvice + @ ExceptionHandler can also achieve global exception capture.

Please make sure that this WebExceptionHandle class can be scanned and loaded into the Spring container.

copy code
 1 @ControllerAdvice

2 @ResponseBody
3 public class WebExceptionHandle {
4 private static Logger logger = LoggerFactory.getLogger(WebExceptionHandle.class);
5 /**
6 * 400-Bad Request
7 */
8 @ResponseStatus(HttpStatus.BAD_REQUEST)
9 @ExceptionHandler(HttpMessageNotReadableException.class)
10 public ServiceResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
11 logger.error("Parameter parsing failed", e);
12 return ServiceResponseHandle.failed("could_not_read_json");
13}
14
15 /**
16 * 405-Method Not Allowed
17 */
18 @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
19 @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
20 public ServiceResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
21 logger.error("The current request method is not supported", e);
22 return ServiceResponseHandle.failed("request_method_not_supported");
23}
24
25 /**
26 * 415-Unsupported Media Type
27 */
28 @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
29 @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
30 public ServiceResponse handleHttpMediaTypeNotSupportedException(Exception e) {
31 logger.error("The current media type is not supported", e);
32 return ServiceResponseHandle.failed("content_type_not_supported");
33}
34
35 /**
36 * 500-Internal Server Error
37 */
38 @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
39 @ExceptionHandler(Exception.class)
40 public ServiceResponse handleException(Exception e) {
41 if (e instanceof BusinessException){
42 return ServiceResponseHandle.failed("BUSINESS_ERROR", e.getMessage());
43}
44
45 logger.error("Service Operation Abnormal", e);
46 e.printStackTrace();
47 return ServiceResponseHandle.failed("server_error");
48}
49 }
copy code

If the exception type to be handled is not declared in the @ExceptionHandler annotation, it will default to the exception type in the parameter list. So it can also be written like this:

copy code
@ControllerAdvice

public class GlobalExceptionHandler {

@ExceptionHandler()
@ResponseBody
String handleException(Exception e){
return "Exception Deal! "+ e.getMessage();
}
}
copy code

The parameter object is the exception object thrown by the Controller layer!

Inherit the ResponseEntityExceptionHandler class to achieve global exception capture for the Rest interface, and can return a custom format:

copy code

< pre> 1 @Slf4j

2 @ControllerAdvice

3 public class ExceptionHandlerBean extends ResponseEntityExceptionHandler {

4

5 /**

6 * Data cannot be found abnormal

7 * @param ex

8 * @param request

9 * @return

10 * @throws IOException

11 */

12 @ExceptionHandler({DataNotFoundException.class})

13 public ResponseEntity handleDataNotFoundException(RuntimeException ex, WebRequest request) throws IOException {

14 return getResponseEntity(ex,request,ReturnStatusCode.DataNotFoundException);

15}

16

17 /**

18 * Construct ResponseEntity entities based on various exceptions. Serve the above various exceptions

19 * @param ex

20 * @param request

21 * @param specificException

22 * @return

23 */

24 private ResponseEntity getResponseEntity(RuntimeException ex, WebRequest request, ReturnStatusCode specificException) {

25

26 ReturnTemplate returnTemplate = new ReturnTemplate();

27 returnTemplate.setStatusCode(specificException);

28 returnTemplate.setErrorMsg(ex.getMessage());

29

30 return handleExceptionInternal(ex, returnTemplate,

31 new HttpHeaders(), HttpStatus.OK, request);

32}

33

34 }

copy code

The above are the three ways Spring handles unified exceptions.

Contents

  • Use @ ExceptionHandler annotation
  • Implement the HandlerExceptionResolver interface
  • Use @ControllerAdvice+ @ ExceptionHandler annotations
  • Reference materials

< img alt="Copy code" src="/wp-content/uploads/images/opensource/spring/1626813516131.gif" >
 1 @Controller

2 public class GlobalController {
3
4 /**
5 * Used to handle exceptions
6 * @return
7 */
8 @ExceptionHandler({MyException.class})
9 public String exception(MyException e) {
10 System.out.println(e.getMessage());
11 e.printStackTrace();
12 return "exception";
13}
14
15 @RequestMapping("test")
16 public void test() {
17 throw new MyException("Something went wrong!");
18}
19}
copy code

copy code

copy code

Back to top

copy code
 1 @Component

2 public class ExceptionTest implements HandlerExceptionResolver{
3
4 /**
5 * TODO briefly describes the realization function of this method (optional).
6 * @see org.springframework.web.servlet.HandlerExceptionResolver#resolveException(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
7 */
8 public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
9 Exception ex) {
10 System.out.println("This is exception handler method!");
11 return null;
12}
13}
copy code

copy code

copy code

Back to top

copy code
 1 @ControllerAdvice

2 @ResponseBody
3 public class WebExceptionHandle {
4 private static Logger logger = LoggerFactory.getLogger(WebExceptionHandle.class);
5 /**
6 * 400-Bad Request
7 */
8 @ResponseStatus(HttpStatus.BAD_REQUEST)
9 @ExceptionHandler(HttpMessageNotReadableException.class)
10 public ServiceResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
11 logger.error("Parameter parsing failed", e);
12 return ServiceResponseHandle.failed("could_not_read_json");
13}
14
15 /**
16 * 405-Method Not Allowed
17 */
18 @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
19 @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
20 public ServiceResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
21 logger.error("The current request method is not supported", e);
22 return ServiceResponseHandle.failed("request_method_not_supported");
23}
24
25 /**
26 * 415-Unsupported Media Type
27 */
28 @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
29 @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
30 public ServiceResponse handleHttpMediaTypeNotSupportedException(Exception e) {
31 logger.error("The current media type is not supported", e);
32 return ServiceResponseHandle.failed("content_type_not_supported");
33}
34
35 /**
36 * 500-Internal Server Error
37 */
38 @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
39 @ExceptionHandler(Exception.class)
40 public ServiceResponse handleException(Exception e) {
41 if (e instanceof BusinessException){
42 return ServiceResponseHandle.failed("BUSINESS_ERROR", e.getMessage());
43}
44
45 logger.error("Service Operation Abnormal", e);
46 e.printStackTrace();
47 return ServiceResponseHandle.failed("server_error");
48}
49 }
copy code

copy code

copy code

copy code
@ControllerAdvice

public class GlobalExceptionHandler {

@ExceptionHandler()
@ResponseBody
String handleException(Exception e){
return "Exception Deal! "+ e.getMessage();
}
}
copy code

copy code

copy code

copy code
 1 @Slf4j

2 @ControllerAdvice
3 public class ExceptionHandlerBean extends ResponseEntityExceptionHandler {
4
5 /**
6 * Data cannot be found abnormal
7 * @param ex
8 * @param request
9 * @return
10 * @throws IOException
11 */
12 @ExceptionHandler({DataNotFoundException.class})
13 public ResponseEntity handleDataNotFoundException(RuntimeException ex, WebRequest request) throws IOException {
14 return getResponseEntity(ex,request,ReturnStatusCode.DataNotFoundException);
15}
16
17 /**
18 * Construct ResponseEntity entities based on various exceptions. Serve the above various exceptions
19 * @param ex
20 * @param request
21 * @param specificException
22 * @return
23 */
24 private ResponseEntity getResponseEntity(RuntimeException ex, WebRequest request, ReturnStatusCode specificException) {
25
26 ReturnTemplate returnTemplate = new ReturnTemplate();
27 returnTemplate.setStatusCode(specificException);
28 returnTemplate.setErrorMsg(ex.getMessage());
29
30 return handleExceptionInternal(ex, returnTemplate,
31 new HttpHeaders(), HttpStatus.OK, request);
32}
33
34 }
copy code

copy code

copy code

Leave a Comment

Your email address will not be published.