SpringBoot handles global consent exception

SpringBoot handles global unified exceptions

When an exception occurs in the backend or an error occurs in the request, the frontend usually displays as follows

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Fri Jun 07 15:38:07 CST 2019
There was an unexpected error (type=Not Found, status=404).
No message available

Very unfriendly to users.

This article mainly explains how to use unified exception handling in SpringBoot applications.

Method to realize

The first: use @ControllerAdvice and @ExceptionHandler annotations

The second: use the ErrorController class to implement.

The first: use @ControllerAdvice and @ExceptionHandler annotations

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler{
    @ResponseBody
    @ExceptionHandler(CustomerException.class)
    public BaseResult handlerCustomerException(CustomerException ex){
        log.info("GlobalExceptionHandler...");
		log.info("error code:"  + response.getStatus());
		BaseResult result = new BaseResult(ex.getExceptionEumns().getCode,"GlobalExceptionHandler:"+ex.getExceptionEumns().getMessage());
        return result;
    }
}

The annotation @ControllerAdvice indicates that this is a controller enhancement class. When an exception occurs in the controller and conforms to the interception exception class defined in the class, it will be intercepted.

You can define the package path where the intercepted controller is located

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};

    Class<?>[] assignableTypes() default {};

    Class<? extends Annotation>[] annotations() default {};
}

Annotation ExceptionHandler defines the intercepted exception class

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
    Class<? extends Throwable>[] value() default {};
}

The second: use the ErrorController class to implement.

The default error handling class of the system is BasicErrorController, which will display the above error page.

Write your own error handling class here, the default handling class above will not work.

The path server returned by getErrorPath() will redirect to the processing class corresponding to the path, in this case the error method.

@Slf4j
@RestController
public class HttpErrorController implements ErrorController {

    private final static String ERROR_PATH = "/error";

    @ResponseBody
    @RequestMapping(path  = ERROR_PATH )
    public BaseResult error(HttpServletRequest request, HttpServletResponse response){
        log.info("access/error" + "  error code:"  + response.getStatus());
        BaseResult result = new WebResult(WebResult.RESULT_FAIL,"HttpErrorController error:"+response.getStatus());return result;
    }
    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }
}

test

The above defines a unified return class BaseResult, which is convenient for front-end processing.

@Data
@NoArgsConstructor
public class BaseResult implements Serializable {

    private static final long serialVersionUID = 1L;

    public static final int RESULT_FAIL = 0;
    public static final int RESULT_SUCCESS = 1;

    //return code
    private Integer  code;

    //return message
    private String message;

    //return object
    private  Object data;

    public BaseResult(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    public BaseResult(Integer code, String message, Object object) {
        this.code = code;
        this.message = message;
        this.data = object;
    }
}
Write a test controller
@Slf4j
@RestController
@RequestMapping("/user")
public class TestController {

    @RequestMapping("/info1")
    public String test(){
      log.info("/user/info1");
      throw new CustomerException("TestController have exception");
    }
}

1. Issue a wrong request, that is, there is no corresponding processing class.

As you can see from the return, it is handled by the HttpErrorController class

{"code":0,"message":"HttpErrorController error:404","data":null}

2. Issue a normal request (TestController's test() processing), and throw an empty exception in the processing class

It can be seen from the return that it is handled by the GlobalExceptionHandler class

{"code":0,"message":"request error:200","data":"GlobalExceptionHandler:TestController have exception"}
the difference

1. The annotation @ControllerAdvice method can only handle exceptions thrown by the controller. At this point the request has entered the controller.

2. The ErrorController-like method can handle all exceptions, including errors that do not enter the controller, such as 404, 401 and other errors

3. If the two coexist in the application, the @ControllerAdvice method handles the exception thrown by the controller, and the class ErrorController method does not enter the controller's exception.

4. The @ControllerAdvice method can define multiple interception methods, intercept different exception classes, and obtain the thrown exception information, with greater freedom.

Tags: Java Spring Spring Boot

Posted by intergroove on Sat, 15 Oct 2022 05:07:46 +0300