This is the 26th day of my participation in the August More Text Challenge

In the Interface service of the SpringBoot project, we defined a uniform return result in the last lecture, but some exceptions generated by the runtime can not be well predicted. Exceptions will be reported before returning the result data, and the data cannot be returned eventually. This leads to problems with our unified results, so we also need to define a unified specification to catch exceptions that occur during program execution.

At this point, three basic and important uniform specifications for SpringBoot development are in place, the first two of which are here:

  • SpringBoot uniformly outputs logs
  • # SpringBoot returns a unified result

Today we’ll look at uniform exception catching again.

Unified SpringBoot exception capture

Custom unified exception classes

Exceptions in Java programs are divided into detectable exceptions and undetectable exceptions. Detectable exceptions must be caught or thrown. Untraceable exceptions, also called runtime exceptions, require global handling to maintain the stability of interface services and the normal return of data.

Before exception processing, we need to define a global unified exception class to cover the types of exceptions we need to handle, the code is as follows

@Data
public class MyException extends RuntimeException{
    private Integer code;

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

    public MyException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getDesc());
        this.code = resultCodeEnum.getCode();
    }

    @Override
    public String toString(a) {
        return "MyException{" + "code=" + code + ", message=" + this.getMessage() + '} '; }}Copy the code

Unified exception handler

@ ControllerAdvice annotations

The @ControllerAdvice annotation is a control-level Advice that aggregates the common @ExceptionHandler, @initBinder, and @ModelAttributes methods into one type and applies them to all controllers. The @ControllerAdvice annotation is central to uniform exception handling in the SpringBoot project.

The process of exception capture can be analyzed as follows:

  1. Annotate the exception handler class with the @ControllerAdvice annotation
  2. Define a generic exception catching method and use the @exceptionhandler annotation to annotate the methods in the ExceptionHandler class to uniformly catch the specified exception information
  3. Customize an exception class to catch exceptions specific to a project or business;
  4. The exception object information is added to the unified result enumeration;

Unified exception handler

Define an exception handling class and annotate it with the @controllerAdvice annotation to identify the current class used for exception handling. In the exception processing class, the general exception processing method, the specific exception type processing method and the custom exception class processing method are defined respectively. The process of exception processing in SpringBoot is from small to small.

@ControllerAdvice
public class GlobalExceptionHandler {

    /** * General exception handling method */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result error(Exception e){
        e.printStackTrace();;
        return Result.error();
    }

    /** * specifies a specific exception handling method */
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public Result error(NullPointerException e){
        e.printStackTrace();
        return Result.setResult(ResultCodeEnum.NULL_POINT_ERROR);
    }

    /** * returns a custom exception handling method */
    @ExceptionHandler(MyException.class)
    @ResponseBody
    public Result error(MyException e){
        e.printStackTrace();
        returnResult.error().code(e.getCode()).desc(e.getMessage()); }}Copy the code

As the code shows, when the exception is a NullPointerException NullPointerException, the method of the exception type parameter is preferentially executed and the result is returned. The same is true for custom exceptions. Only if the exception does not fall into these two categories will the general exception handling method be called to handle the current exception information.

The control layer catches the exception and returns it

Once we have defined the global exception class and defined the exception handler and the corresponding exception handling methods using the @ControllerAdvice annotation, we can define the corresponding interface service in the Controller control layer and test whether the global exception we defined is in effect. The following is the custom interface information, which calls NULL internally and generates a NullPointerException

@RequestMapping(value = "/null")
public String nullException(a){
    List<String> list = null;
    Integer count = list.size();
    return "success";
}
Copy the code

Upon a request to this interface, the result is returned:

{" success ": false," code ": 20003," desc ":" null pointer exception ", the "data" : null}Copy the code

Indicates that the exception handler we defined has taken effect.

The last

Our custom exception has play a role in the service interface, and can according to the type of exception and find corresponding methods for handling, eventually add exception information to the results of the unified class, as a service interface data returned to the caller, so we can guarantee the service interface specification uniformity and stable results.