Global exception handling and unified response object of springboot

Posted by stuartshields on Sat, 25 Dec 2021 23:08:28 +0100

1, springboot exception handling

1. The default exception handling mechanism of springboot

By default, SpringBoot provides two different ways to respond

  1. One is that when the browser client requests a nonexistent page or server exception, SpringBoot will respond to an html by default

  2. The other is to return json information by default when using debugging tools such as postman to request non-existent URLs or server-side exceptions

2.SpringBoot global exception handling

Generally, we will not return the error information to the front end and try to catch exceptions by ourselves, but there is a problem: it is certainly inappropriate for each method to catch exceptions in this way. This is why we need global exception handling.

@RestController
public class ExceptionController {
    @GetMapping("exceptionA")
    public void methodA() {
        try {
            int a = 100 / 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2.1 local exception handling

Use the @ EceptionHandle annotation to implement local exception handling of a class

   @RestController
   public class ExceptionController {
   
       @GetMapping("exceptionA")
       public void methodA() {
           int a = 100 / 0;
       }
   
       /**
        * Local exception handling
        */
       @ExceptionHandler(Exception.class)
       public String exHandler(Exception e) {
           // Judge the type of exception except 0, and respond to the exception
           if (e instanceof ArithmeticException) {
               return "Exception except 0 occurred";
           }
           // Respond to an unknown exception
           return "An unknown exception occurred";
       }
   }

2.2 global exception handling

Use the @ ControllerAdvice +@ExceptionHandler annotation to implement global exception handling

Customize an exception class

@RestControllerAdvice
public class DefaultException {
​
    @ExceptionHandler({NullPointerException.class})
    public String exception(NullPointerException exception) {
        return "Null pointer exception";
​
    }
​
    @ExceptionHandler({IndexOutOfBoundsException.class})
    public String exception(IndexOutOfBoundsException exception) {
        return "Array out of bounds exception";
    }
}

An exception method test is added. Because local exceptions have higher priority, they are commented out first

@RestController
public class ExceptionController {
​
    @GetMapping("exceptionA")
    public void methodA() {
        int a = 100 / 0;
    }
​
    @GetMapping("exceptionB")
    public void methodB() {
        List list = new ArrayList<>();
        System.out.println(list.get(0));
    }
​
    /**
     * Local exception handling
     */
    //@ExceptionHandler(Exception.class)
    //public String exHandler(Exception e) {
    // / / judge the type of exception except 0, and respond to the exception
    //    if (e instanceof ArithmeticException) {
    // return "exception except 0 occurred";
    //    }
    // / / respond to unknown exceptions
    // return "an unknown exception occurred";
    //}
}

Global exception annotation is in effect

3. Custom exception

Custom exceptions only need to inherit the exception class or its subclasses

@Data
@NoArgsConstructor
public class CustomException extends Exception {
​
    private static final long serialVersionUID = 1L;
​
    private Integer code;
​
    private String mes;
​
    /**
     * @param code Status code
     * @param msg  Exception return information
     * @description constructor 
     */
    public CustomException(Integer code, String msg) {
        super(msg);
        this.code = code;
    }
}

You can throw exception objects directly when using

@GetMapping("exceptionC")
public void methodC() throws CustomException {
    int a = 1;
    if (a == 1) {
        throw new CustomException(10086, "Custom exception");
    }
}

2, Unified response object

In actual development, we need to encapsulate a unified response object and distinguish between status code and information for front-end processing.

1. Define a unified response object

It generally includes status code, error information, data, etc.

Customize some methods to return information, such as the success () failed () method I defined

@Data
@NoArgsConstructor
@AllArgsConstructor
public class R<T> {
    /**
     * Return status code
     */
    private Integer code;
    /**
     * Return information
     */
    private String msg;
    /**
     * data
     */
    private T data;
​
    public static R success() {
        return new R(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), null);
    }
​
    public static R success(Object data) {
        return new R(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), data);
    }
​
    public static R failed() {
        return new R(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMsg(), null);
    }
​
    public static R failed(String msg) {
        return new R(ResultCode.FAILED.getCode(), msg, null);
    }
​
    public static R failed(int code, String msg) {
        return new R(code, msg, null);
    }
}

2. Enumeration information

Enumerate some common status information

Let me give you an example. Just enumerate 2 and customize them as needed

@NoArgsConstructor
@AllArgsConstructor
public enum ResultCode {
​
    SUCCESS(200, "Request succeeded"),
    FAILED(500, "Server error");
​
    private int code;
    private String msg;
​
    public int getCode() {
        return code;
    }
​
    public void setCode(int code) {
        this.code = code;
    }
​
    public String getMsg() {
        return msg;
    }
​
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

3. Response object

When using, just return the defined object type directly, and change the defined global exception return type to a unified response object

@RestControllerAdvice
public class DefaultException {
    @ExceptionHandler({CustomException.class})
    public R exception(CustomException e) {
        return R.failed(e.getCode(),e.getMessage());
    }
​
    @ExceptionHandler({Exception.class})
    public R exception(Exception e) {
        return R.failed(e.getMessage());
    }
}

last

I've always wanted to sort out a perfect interview dictionary, but I can't spare time. This set of more than 1000 interview questions is sorted out in combination with the interview questions of gold, silver and four major factories this year, as well as the documents with star number exceeding 30K + on GitHub. After I uploaded it, it's no surprise that the praise amount reached 13k in just half an hour. To be honest, it's still a little incredible.

You need a full version of the little partner. You can click three times, click here !

1000 Internet Java Engineer Interview Questions

Content: Java, MyBatis, ZooKeeper, Dubbo, Elasticsearch, Memcached, Redis, MySQL, Spring, SpringBoot, SpringCloud, RabbitMQ, Kafka, Linux and other technology stacks (485 pages)

Collection of Java core knowledge points (page 283)

The content covers: Java foundation, JVM, high concurrency, multithreading, distribution, design pattern, Spring bucket, Java, MyBatis, ZooKeeper, Dubbo, Elasticsearch, Memcached, MongoDB, Redis, MySQL, RabbitMQ, Kafka, Linux, Netty, Tomcat, database, cloud computing, etc

Collection of advanced core knowledge points in Java (page 524)

Sorting out knowledge points of Java advanced architecture

 

Due to space constraints, the detailed information is too comprehensive and there are too many details, so only the screenshots of some knowledge points are roughly introduced. There are more detailed contents in each small node!

You need a full version of the little partner. You can click three times, click here !

Topics: Java Spring Boot