Project development in order to zero seems impossible, whether a system exception or the program itself coding problem caused by the abnormal information must be returned in a conventional data structure, friendly treatment in front and back end separation mode (backend API interface to the front-end) can greatly increase the communication and work efficiency. This article mainly uses the @controllerAdvice annotation for unified exception handling based on Spring Boot.

Quick navigation

  • Uniform return data structure
    • [Unified return data structure]Define the interface return data structure
    • [Unified return data structure]Data interface field model definition
    • [Unified return data structure]Encapsulating interface return methods (success, failure)
  • Unified Exception Handling
    • [Unified exception handling]Status message enumeration
    • [Unified exception handling]Custom exception classes
    • [Unified exception handling]@controllerAdvice Handle exceptions uniformly
  • test
    • [test]Test normal return and null pointer system exception
    • [test]Custom exception tests

This article is based on the Spring Boot Practice series (3)AOP aspect programming /chapter3/chapter3-1 available on Github source code

Uniform return data structure

Define the interface return data structure

First, define the data structure returned by the interface. If code is 0, the operation is successful; if code is not 0, the operation is abnormal. Data is returned only if the processing is successful, not otherwise, or for interfaces that do not need to return data (update, delete…).

{
 	"code": 0."message": "SUCCESS"."data": {}}Copy the code

Data interface field model definition

Create the /domain/ result. Java class to define the fields involved in the above data interface.

Result.java

package com.angelo.domain;

public class Result<T> {
    private Integer code; / / status code

    private String message; // Status description

    private T data; // define as a stereotype

    // The following getter and setter methods are omitted
}
Copy the code

Encapsulate the interface return method

Create the /util/ messageutil. Java class to uniformly encapsulate returned successes and failures.

MessageUtil.java

package com.angelo.util;

import com.angelo.domain.Result;

public class MessageUtil {

    /** ** successful method *@param object
     * @return* /
    public static Result success(Object object) {
        Result result = new Result();
        result.setCode(0);
        result.setMessage("SUCCESS");
        if(object ! =null) {
            result.setData(object);
        }

        return result;
    }

    /** * succeeded but */
    public static Result success(a) {
        return success(null);
    }

    /** * failed method *@param code
     * @param message
     * @return* /
    public static Result error(Integer code, String message) {
        Result result = new Result();
        result.setCode(code);
        result.setMessage(message);

        returnresult; }}Copy the code

Unified Exception Handling

Status message enumeration

The status code and description information used by the project should be uniformly defined by a file. On the one hand, it can be reused. On the other hand, if the status code and description are changed, it only needs to be changed at the place where the enumeration is defined.

Create /enums/MessageEnum. Java enumeration

package com.angelo.enums;

public enum MessageEnum {
    SYSTEM_ERROR(1001."System exception"),
    NAME_EXCEEDED_CHARRACTER_LIMIT(2000."Name exceeds limit, maximum 4 characters!");

    private Integer code;

    private String message;

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

    public Integer getCode(a) {
        return code;
    }

    public String getMessage(a) {
        returnmessage; }}Copy the code

Custom exception classes

The Spring Boot framework only rolls back objects to thrown RuntimeExceptions, so Spring Boot encapsulates runtimeExceptions as inherited exceptions

New/exception/UserException. Java classes, inherit from RuntimeException

UserException.java

package com.angelo.exception;

import com.angelo.enums.MessageEnum;

public class UserException extends RuntimeException {
    private Integer code;

    public UserException(MessageEnum messageEnum) {
        super(messageEnum.getMessage());
        this.code = messageEnum.getCode();
    }

    public Integer getCode(a) {
        return code;
    }

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

@controllerAdvice Handle exceptions uniformly

More content on @ ControllerAdvice https://docs.spring.io/spring-framework/docs/5.0.0.M1/javadoc-api/org/springframework/web/ may refer to the official document bind/annotation/ControllerAdvice.html

  • @controlleradvice, new in spring3.2, defines @exceptionhandler, @initbinder, and @modelattribute methods and applies them to all @requestmapping methods.

  • ExceptionHandler. Value in this method refers to the type of exception to be blocked. You can use this annotation to customize exception handling.

  • Note:I’ve talked about AOP aspect oriented programming, annotations@AfterThrowingError messages are caught in the project. If you use this annotation, it will return when it catches the error message@ControllerAdviceAnnotations.
package com.angelo.handle;

import com.angelo.domain.Result;
import com.angelo.exception.UserException;
import com.angelo.util.MessageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class ExceptionHandle {

    private final static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result handle(Exception e) {
        logger.info("Enter the error");

        // Whether it is a custom exception
        if (e instanceof UserException) {
            UserException userException = (UserException) e;

            return MessageUtil.error(userException.getCode(), userException.getMessage());
        } else {
            logger.error("System exception {}", e);

            return MessageUtil.error(1000."System exception!"); }}}Copy the code

test

Test normal return and null pointer system exception

Modify the userController. Java class to add return value handling to the query user list interface, as shown below:

/** * Query the user list *@return* /
@RequestMapping(value = "/user/list/{exception}")
public Result<User> userList(@PathVariable("exception") Boolean exception) {
    if (exception) {
        return null; // Test for null pointer exceptions
    }

    return MessageUtil.success(userRepository.findAll());
}
Copy the code
  • Return to success

  • Return system exception

Custom exception tests

Modify the userController. Java class to add a custom error in the interface for saving user information, as shown below:

/** * save a user *@param name
 * @param age
 * @return* /
@PostMapping(value = "/user")
public User userAdd(@RequestBody User userParams) throws Exception {
    User user = new User();
    user.setName(userParams.getName());
    user.setAge(userParams.getAge());

    if (userParams.getName().length() > 4) { // Verify the test exception class
        throw new UserException(MessageEnum.NAME_EXCEEDED_CHARRACTER_LIMIT);
    }

    return userRepository.save(user);
}
Copy the code

Github see the full example chapter4-1 for this article

Author: you may link: www.imooc.com/article/260… Github: Spring Boot