How to achieve unified exception handling in spring boot project

In a project, there are inevitably various exceptions. We hope that the exception information can be as detailed as possible, including the response status code, the response string exception information, and even the operation time, etc., so that we can easily and quickly locate the location where the exception occurs. Therefore, the exception handling in a project is particularly important. Then, the small editor uses the spring boot framework, The unified exception handling method is demonstrated by code examples

1. First, we simply build a spring boot framework project. The project name is exceptionhandler

2. Import related dependencies

Import lombok dependency and provide @ getter annotation

Import the date tool class JodaTime, and provide the DateTime.now() method

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--Date tool class:JodaTime-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

3. Write application.yml configuration file

Note that the access path prefix is added here

server:
  port: 8082
  servlet:
    context-path: /exception

4. Write the startup class of SpringBoot

package com.exception;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ExceptionApplication {
    public static void main(String[] args) {
        SpringApplication.run(ExceptionApplication.class, args);
    }
}

5. Write exception enumeration class

In the exception enumeration class, all the possible exception types of the project should be listed. Here, just take the example of mathematical calculation exception

package com.exception.enums;

import lombok.Getter;

/**
 * Exception enumeration class
 */
@Getter
public enum ExceptionEnum {
    ARTITHMETIC(500, "Mathematical calculation abnormality");
    private Integer status;
    private String message;

    ExceptionEnum(Integer status, String message) {
        this.status = status;
        this.message = message;
    }
}

6. Write a custom exception class

The custom Exception class inherits the RuntimeException, while the RuntimeException inherits the Exception class, while the Exception inherits the Throwable class. The super method is also the method in Throwable

package com.exception.exceptions;

import com.exception.enums.ExceptionEnum;
import lombok.Getter;

/**
 * Custom exception class
 */
@Getter
public class SelfDefinedException extends RuntimeException {
    private Integer status;

    public SelfDefinedException(ExceptionEnum exceptionEnum) {
        super(exceptionEnum.getMessage());
        this.status = exceptionEnum.getStatus();
    }

    public SelfDefinedException(ExceptionEnum exceptionEnum, Throwable cause) {
        super(exceptionEnum.getMessage(), cause);
        this.status = exceptionEnum.getStatus();
    }
}

7. Write unified exception return result class

package com.exception.entity;

import com.exception.exceptions.SelfDefinedException;
import lombok.Getter;
import org.joda.time.DateTime;

/**
 * Unified exception return result class
 */
@Getter
public class ExceptionResult {
    private Integer status;
    private String message;
    private String timestamp;

    public ExceptionResult(SelfDefinedException e) {
        this.status = e.getStatus();
        this.message = e.getMessage();
        this.timestamp = DateTime.now().toString("yyyy-MM-dd HH:mm:ss");
    }
}

8. Write unified exception interception class

Note the role of two spring annotations:

@ControllerAdvice: by default, all classes annotated with @ Controller will be blocked

@ExceptionHandler(): this annotation is used on methods. It declares the exception types to be handled in parentheses. Multiple exception types can be specified. Here we specify a custom exception

package com.exception.advice;

import com.exception.entity.ExceptionResult;
import com.exception.exceptions.SelfDefinedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * Unified exception interception class
 */
@ControllerAdvice
@Slf4j
public class BasicExceptionAdvice {
    @ExceptionHandler(SelfDefinedException.class)
    public ResponseEntity<ExceptionResult> handlerException(SelfDefinedException e) {//Parameter type and exception type to be handled must match
        return ResponseEntity.status(e.getStatus()).body(new ExceptionResult(e));//body Objects in must be and ResponseEntity Consistent objects in
    }
}

9. Write test class

package com.exception.controller;

import com.exception.enums.ExceptionEnum;
import com.exception.exceptions.SelfDefinedException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class TestController {
    @GetMapping("/test")
    public ResponseEntity<String> login() {
        try {
            Integer tempValue = 10 / 0;
        } catch (Exception e) {
            throw new SelfDefinedException(ExceptionEnum.ARTITHMETIC);//catch After catching exception,Here throw Exception thrown not handled,So the following code will not execute
        }
        return ResponseEntity.ok("No abnormality found,Returns the correct string");
    }
}

10. Test results

Test through the HTTP Client provided by IDEA, and observe the response results as follows. Then we get

Conclusion:

Because there are all kinds of exceptions in the project, we enumerate all the exceptions through an exception enumeration class. We want to catch the exceptions defined by ourselves, so we wrote a custom exception class. At the same time, we want to respond to the detailed exception result rules, so we implement it through a unified exception result class, We also need an exception interceptor class, so that when we throw a custom exception, the exception interceptor class can intercept and return the response result (that is, all the information of the exception body) that we have defined

Tags: Java Lombok Spring Maven SpringBoot

Posted on Sun, 08 Mar 2020 22:27:26 -0700 by MetaDark