统一结果返回&统一异常处理

统一结果返回&统一异常处理

你们项目中是怎么统一返回前台数据的呢?自定义的异常信息又是怎么封装的呢?因为所在公司封装好像不是那么好,还是觉得有必要自己该写一套,权当是练手而已!

自定义异常枚举类

package com.demo.study.common.constant;

import lombok.Getter;
@Getter
public enum ResultCodeEnum {
    SUCCESS(true, 0000,"成功"),
    UNKNOWN_REASON(false, 0001, "未知错误"),
    BAD_SQL_GRAMMAR(false, 0002, "sql语法错误"),
    JSON_PARSE_ERROR(false, 0003, "json解析异常"),
    PARAM_ERROR(false, 0004, "参数不正确"),
    FILE_UPLOAD_ERROR(false, 0005, "文件上传错误"),
    EXCEL_DATA_IMPORT_ERROR(false, 0006, "Excel数据导入错误");

    private Boolean success; // 是否响应成功
    private Integer code;    // 响应的状态码
    private String message;  // 响应的消息

    ResultCodeEnum(Boolean success, Integer code, String message) {
        this.success = success;
        this.code = code;
        this.message = message;
    }
}

自定义全局异常类

package com.demo.study.common.handler;

import com.demo.study.common.constant.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(value = "全局异常")
public class GlobalException extends RuntimeException{

    @ApiModelProperty(value = "状态码")
    private Integer code;

    /**
     * 接收自定传递的状态码和消息
     * @param code
     * @param message
     */
    public GlobalException(Integer code, String message){
        super(message);
        this.code = code;
    }

    /**
     * 接收枚举类型参数
     */
    public GlobalException(ResultCodeEnum resultCodeEnum){
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
    }


    @Override
    public String toString() {
        return "GlobalException{" +
                "message=" + this.getMessage() +
                "code=" + code +
                '}';
    }
}

自定义返回结果

package com.demo.study.common.entity;

import com.demo.study.common.constant.ResultCodeEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;

@Data
@ApiModel(value = "全局的统一返回结果")
public class Result {

    @ApiModelProperty(value = "是否成功")
    private Boolean success;

    @ApiModelProperty(value = "返回状态码")
    private Integer code;

    @ApiModelProperty(value = "返回消息")
    private String message;

    @ApiModelProperty(value = "返回的数据!")
    private Map<String,Object> data = new HashMap<>();

    public Result() {
    }

    // ok 返回
    public static Result ok(){
        Result r = new Result();
        r.setSuccess(ResultCodeEnum.SUCCESS.getSuccess());
        r.setCode(ResultCodeEnum.SUCCESS.getCode());
        r.setMessage(ResultCodeEnum.SUCCESS.getMessage());
        return r;
    }

    // error 返回
    public static Result error(){
        Result r = new Result();
        r.setSuccess(ResultCodeEnum.UNKNOWN_REASON.getSuccess());
        r.setCode(ResultCodeEnum.UNKNOWN_REASON.getCode());
        r.setMessage(ResultCodeEnum.UNKNOWN_REASON.getMessage());
        return r;
    }

    // setResult 自定义返回
    public static Result definedResult(ResultCodeEnum resultCodeEnum){
        Result r = new Result();
        r.setSuccess(resultCodeEnum.getSuccess());
        r.setCode(resultCodeEnum.getCode());
        r.setMessage(resultCodeEnum.getMessage());
        return r;
    }

    // 这些是为了我们方便链式编程
    public Result success(Boolean success){
        this.setSuccess(success);
        return this;
    }
    public Result message(String message){
        this.setMessage(message);
        return this;
    }
    public Result code(Integer code){
        this.setCode(code);
        return this;
    }
    public Result data(String key,Object value){
        this.data.put(key,value);
        return this;
    }

    public Result data(Map<String,Object> map){
        this.setData(map);
        return this;
    }
}

全局异常处理类

package com.demo.study.common.handler;


import com.demo.study.common.constant.ResultCodeEnum;
import com.demo.study.common.entity.Result;
import com.demo.study.common.util.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    // 处理的所有的 Exception
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result error(Exception e){
        e.printStackTrace();
        return Result.error();
    }

    // 处理自己写的统一异常 CodingException
    @ExceptionHandler(GlobalException.class)
    @ResponseBody
    public Result error(GlobalException e){
        log.error(ExceptionUtil.getStackMessage(e));
        return Result.error().message(e.getMessage()).code(e.getCode());
    }

    // 优先匹配精确的异常
    @ExceptionHandler(BadSqlGrammarException.class)
    @ResponseBody
    public Result error(BadSqlGrammarException e){
        e.printStackTrace();
        return Result.definedResult(ResultCodeEnum.BAD_SQL_GRAMMAR);
    }
}

异常工具类

package com.demo.study.common.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

// 打印异常的堆栈信息
public class ExceptionUtil {

    /**
     * 打印异常堆栈信息
     * @param e
     * @return
     */
    public static String getStackMessage(Exception e){
        // 流
        StringWriter sw = null;
        PrintWriter pw = null;
        try {
            // 将出错的信息输出到 PrintWriter!
            sw = new StringWriter();
            pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            pw.flush();
            sw.flush();
        } catch (Exception e1) {
            e1.printStackTrace();
        } finally {
            if (sw!=null){
                try {
                    sw.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            if (pw!=null){
                pw.close();
            }
        }
        return sw.toString();
    }
}

简单应用

package com.demo.study.service.impl;

import com.demo.study.common.constant.ResultCodeEnum;
import com.demo.study.common.entity.Result;
import com.demo.study.common.handler.GlobalException;
import com.demo.study.common.handler.GlobalExceptionHandler;
import com.demo.study.common.util.ExceptionUtil;
import com.demo.study.entity.User;
import com.demo.study.mapper.UserMapper;
import com.demo.study.service.USERervice;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Echo
 * @since 2020-05-10
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements USERervice {

    @Override
    public Result testOkReturn() {
        Result r = null;
        try{
            // 逻辑获取返回数据
            List<Map<String,Object>> returnList = new ArrayList<>();
            r = Result.ok().data("list",returnList);
        }catch(GlobalException e){
            return  new GlobalExceptionHandler().error(e);
        }
        return r;
    }

    @Override
    public Result definedErrorReturn() {
        Result r = null;
        try{
            // 逻辑获取返回数据
            List<Map<String,Object>> returnList = new ArrayList<>();
            if(returnList.size() == 0){
                r = Result.definedResult(ResultCodeEnum.BAD_SQL_GRAMMAR);
            }
        }catch(GlobalException e){
            return  new GlobalExceptionHandler().error(e);
        }
        return r;
    }
}

好了,至此所有的异常处理和返回封装都已处理完毕;你的项目是不是也可以改呢?加油,奥利给!