SpringBoot Actual Warfare | Unified Handling of Exceptions

Posted by niwa3836 on Mon, 06 May 2019 16:45:04 +0200

Wechat Public Number: An Excellent Abandoned Person
If you have any questions or suggestions, please leave a message in the background. I will try my best to solve your problems.

Preface

For example, today we introduce how SpringBoot handles global exceptions in a unified way. The two main annotations for global exception handling in SpringBoot are @Controller Advice and @ExceptionHandler, where @Controller Advice is a component annotation. Classes with this annotation can intercept Controller requests, while ExceptionHandler annotations can set exception types in global processing control to intercept exceptions to be handled. For example: @ExceptionHandler(value = NullPointException.class).

Dead work

  • SpringBoot 2.1.3
  • IDEA
  • JDK 8

Dependency configuration

<dependencies>
        <!-- JPA rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!-- web rely on -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- mysql Connection class -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- lombok rely on -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- Unit test dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

configuration file

spring:
  # Database correlation
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&useSSL=true
    username: root
    password: 123456

  jpa:
    hibernate:
      ddl-auto: update   #ddl-auto: Set create to indicate that the table is rebuilt every time
    show-sql: true

Return message class

public class Message<T> implements Serializable {

    /**
     * Status code
     */
    private Integer code;

    /**
     * Return information
     */
    private String message;

    /**
     * Data class returned
     */
    private T data;

    /**
     * time
     */
    private Long time;

    // getter, setter, and construction strategy...
}

Tool class

Code comments are very detailed for processing the returned data and information classes.

public class MessageUtil {

    /**
     * Successfully and returns the data entity class
     * @param o
     * @param <E>
     * @return
     */
    public static <E>Message<E> ok(E o){
        return new Message<>(200, "success", o, new Date().getTime());
    }

    /**
     * Successful, but no data entity class returned
     * @return
     */
    public static <E>Message<E> ok(){
        return new Message<>(200, "success", null, new Date().getTime());
    }

    /**
     * Failed, custom exception returned
     * @param code
     * @param msg
     * @return
     */
    public static <E>Message<E> error(Integer code,String msg){
        return new Message<>(code, msg, null, new Date().getTime());
    }
}

Custom exceptions

By inheriting RuntimeException, code is declared to be used to define different types of custom exceptions. Mainly used for exceptional interception to get code and set code to the message class to return.

public class CustomException extends RuntimeException{

    /**
     * Status code
     */
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public CustomException(Integer code, String message){

        super(message);
        this.code = code;

    }
}

Abnormal interception class

Declare that this class can intercept Controller requests by adding @RestController Advice, and add @ExceptionHandler to the handle method and specify the exception class to intercept in the annotation.

@RestControllerAdvice // Controller Enhancement Processing (returning JSON-formatted data), classes with this annotation can be automatically found by classpath scans
public class ExceptionHandle {

    @ExceptionHandler(value = Exception.class) // Capture the specified type of exception thrown in Controller, or specify other exceptions
    public <E>Message<E> handler(Exception exception){

        if (exception instanceof CustomException){
            CustomException customException = (CustomException) exception;
            return MessageUtil.error(customException.getCode(), customException.getMessage());
        } else {
            return MessageUtil.error(120, "Exception information:" + exception.getMessage());
        }
    }
}

Only custom exceptions and unknown exceptions are handled here. If you explicitly know that an exception might be thrown in a method, you can add a specific processing. For example, you clearly know that this method may throw NullPoint Exception and add NullPoint Exception processing:

if (exception instanceof CustomException){
     CustomException customException = (CustomException) exception;
     return MessageUtil.error(customException.getCode(), customException.getMessage());
} else if (exception instanceof NullPointException ){
     return MessageUtil.error(500, "Null pointer exception message!");
} else {
     return MessageUtil.error(120, "Exception information:" + exception.getMessage());
}

controller layer

@RestController
@RequestMapping("/student")
public class StudentController {

    @Autowired
    private StudentService studentService;

    @GetMapping("/{id}")
    public Message<Student> findStudentById(@PathVariable("id") Integer id){

        if (id < 0){
            //Test custom errors
            throw new CustomException(110, "Parameters cannot be negative!");

        } else if (id == 0){
            //Hardcoded for testing
            Integer i = 1/id;
            return null;
        } else {
            Student student = studentService.findStudentById(id);
            return MessageUtil.ok(student);
        }
    }
}

Complete code

https://github.com/turoDog/De...

If you find it helpful, please give a Star and go again. Thank you very much.

Postman test

Visit http://localhost 8080/student/5 test normal return data results.

Visit http://localhost 8080/student/0 tests the results of unknown anomalies.

Visit http://localhost 8080/student/-11 tests the results of custom exceptions.

Posterior language

If this article is even a little helpful to you, please help to look good. Your good looks are my motivation to keep writing.

In addition, free learning materials are available after 1024 is sent. For more information, please refer to this old article: Python, C++, Java, Linux, Go, Front-end, Algorithmic Data Sharing

Topics: Java MySQL Spring SpringBoot