Bootstrap

Spring Boot项目系列(3)项目中统一异常处理,统一标准返回格式,统一错误返回码

前言

spring boot 项目中的MVC分层,在controller层我们需要做的是什么,统一项目中的返回格式,统一异常的统一处理,统一错误的返回码。项目中的三个统一息息相关,互相联系。gitee:

https://gitee.com/shen_wen_jia/learning-projects/tree/master/%E7%BB%9F%E4%B8%80%E8%BF%94%E5%9B%9E%E6%A0%BC%E5%BC%8Fresponse

项目架构

项目架构

 
 

1.统一标准返回格式

     项目中在controller层出现的各种返回,例:List ,Map<String,Object>。返回的数据多种多样,不方便与前端做一个统一的交互。统一标准返回格式,将各种返回对象分装在自己的BaseResponse当中。主要封装三个对象,code,msg,data。code-返回信息码(主要用来描述错误码)。msg-返回信息描述(主要用来描述错误信息)。data-正确数据/异常信息

Baseresponse的封装:

package com.study.res.comm;

import com.study.res.enums.ErrorEnum;

import javax.management.openmbean.TabularData;
import java.io.Serializable;

/**
 * @ClassName BaseResponse
 * @Author swj
 * @Date 2020/10/10 10:08
 */
public class BaseResponse<T> implements Serializable {

    private static final long serialVersionUID = 9211889136173018364L;

    /**
     * 成功返回码
     */
    private static final int SUCCESS_CODE = 200;

    /**
     * 成功返回信息
     */
    private static final String SUCCESS_MSG = "SUCCESS";

    /**
     * 返回信息标识码
     */
    private int code = SUCCESS_CODE;

    /**
     * 返回信息描述信息
     */
    private String msg = SUCCESS_MSG;

    /**
     * 响应内容-默认为空
     */
    private T data = null;


    /**
     * 返回空的正确返回
     * @return
     */
    public static BaseResponse retOk(){
        return new BaseResponse();
    }

    /**
     * 有内容的成功信息返回
     * @param data
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> retOk(T data){
        BaseResponse<T> baseResponse = new BaseResponse<T>();
        baseResponse.setData(data);
        return baseResponse;
    }

    /**
     * 失败版本返回 enum 版本
     * @param errorEnum
     * @return
     */
    public static BaseResponse retFail(ErrorEnum errorEnum){
        return retFail(errorEnum.getRespCode(),errorEnum.getRespMsg());
    }

    /**
     * 无失败内容返回
     * @param code
     * @param msg
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> retFail(int code,String msg){
        BaseResponse<T> response = new BaseResponse<>();
        response.setCode(code);
        response.setMsg(msg);
        return response;
    }

    /**
     * 有失败的返回格式 enum版本
     * @param errorEnum
     * @param data
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> retFail(ErrorEnum errorEnum,T data) {
        BaseResponse<T> response = new BaseResponse<>();
        response.setCode(errorEnum.getRespCode());
        response.setMsg(errorEnum.getRespMsg());
        response.setData(data);
        return response;
    }

    /**
     * 有失败的返回格式
     * @param code
     * @param msg
     * @param data
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> retFail(int code, String msg, T data){
        BaseResponse<T> response = new BaseResponse<>();
        response.setCode(code);
        response.setMsg(msg);
        response.setData(data);
        return response;
    }

    public void setData(T data) {
        this.data = data;
    }

    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;
    }

    public T getData() {
        return data;
    }
}

 
 

2.统一异常处理

     项目中,将会遇到很多的异常,对统一的异常加以处理,统一解决项目当中的各种异常,并且将异常描述信息返回给前端。这里是将异常信息,统一处理,统一加入json返回,而不是spring boot 项目中的默认返回界面 /error

代码中生效的主要有2个注解:

@ControllerAdvice //将本类加入spring管理

@ExceptionHandler(value = WebException.class) //接收需要处理的异常类

自定义异常:

package com.study.res.exception;

/**
 * @ClassName WebException
 * @Author swj
 * @Date 2020/10/10 10:28
 */
public class WebException extends Exception {

    public WebException(String msg){
        super(msg);
    }
}

代码如下:

package com.study.res.controller;

import com.study.res.comm.BaseResponse;
import com.study.res.enums.ErrorEnum;
import com.study.res.exception.WebException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

/**
 * @ClassName UnifyExceptionHandler
 * @Author swj
 * @Date 2020/10/10 10:32
 * controller层的异常统一处理类
 */
@ControllerAdvice
public class UnifyExceptionHandler {

    @ResponseBody
    @ExceptionHandler(value = WebException.class)
    public BaseResponse handleWebException(HttpServletRequest req, WebException e){
        return BaseResponse.retFail(ErrorEnum.SYSTEM_EXCEPTION,e);
    }

}

 
 

3.统一错误返回码

     错误标准码的定义,各个公司都不一定,建议按照阿里规范错误返回码来。给出自定义的错误返回码。错误返回enum的使用,主要是结合统一返回格式进行使用,给出固定的项目中的错误返回码,和错误返回描述信息。

代码如下:

package com.study.res.enums;

/**
 * @ClassName ErrorEnum
 * @Author swj
 * @Date 2020/10/10 10:22
 */
public enum  ErrorEnum {
    DUPLICATE_KEY(1000,"标识符重复"),
    DUPLICATE_ROLE_NAME(1001,"角色名重复"),
    DUPLICATE_USER_CODE(1002,"用户账号重复"),
    USER_NOT_LOGIN(1003,"用户未登录"),
    QUESTIONNAIRE_PARAM_IS_NULL(2000,"类型或问题详情为空"),
    PARAM_IS_NULL(2001,"参数为空"),
    SYSTEM_EXCEPTION(500,"服务器发生异常")
            ;

    private Integer respCode;
    private String respMsg;

    ErrorEnum(Integer respCode, String respMsg) {
        this.respCode = respCode;
        this.respMsg = respMsg;
    }
    public Integer getRespCode() {
        return respCode;
    }
    public String getRespMsg() {
        return respMsg;
    }
}

 
 
 

4.测试效果

     编写controller层代码测试代码相关效果

package com.study.res.controller;

import com.study.res.comm.BaseResponse;
import com.study.res.enums.ErrorEnum;
import com.study.res.exception.WebException;
import com.study.res.pojo.User;
import org.springframework.web.bind.annotation.*;

/**
 * @ClassName UserController
 * @Author swj
 * @Date 2020/10/10 10:08
 */
@RestController
@RequestMapping("/test")
public class UserController  {

    @GetMapping(value = "/exception")
    public BaseResponse get(@RequestParam Integer flag) throws WebException{
        if (flag == 0){
            throw new WebException("my test");
        }else if(flag == 1){
            return BaseResponse.retOk();
        } else if(flag ==2){
            User u = new User();
            u.setPassword("swj");
            u.setUserName("swj");
            return BaseResponse.retOk(u);
        }else {
            return BaseResponse.retFail(ErrorEnum.DUPLICATE_USER_CODE);
        }
    }
    
    @PostMapping(value = "/test")
    public BaseResponse get(@RequestBody User user) throws WebException{
        //假设项目中出现异常,解决相关异常的同时,抛出自己定义的异常
        try{
            System.out.println(user.toString());
        }catch (Exception e){
            throw new WebException(e.toString());
        }
        return BaseResponse.retOk();
    }
}

 
 
 
测试结果:

正确结果

在这里插入图片描述

错误结果:

在这里插入图片描述

异常结果:
在这里插入图片描述

 
 
 
 
 
 
 
 
 
 
 

路漫漫其修远兮,吾将上下而求索

;