天天看點

統一結果傳回&統一異常處理

@

目錄

  • 自定義異常枚舉
  • 自定義全局異常
  • 自定義傳回結果
  • 全局異常處理
  • 異常工具類
  • 簡單應用
你們項目中是怎麼統一傳回前台資料的呢?自定義的異常資訊又是怎麼封裝的呢?因為所在公司封裝的好像不是那麼好,還是覺得有必要自己該寫一套,權當是練手而已!

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().code(e.getCode()).message(e.getMessage());
    }

    // 優先比對精确的異常
    @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;
    }
}
           
好了,至此所有的異常處理和傳回封裝都已處理完畢;你的項目是不是也可以改改呢?加油,奧利給!

餘路那麼長,還是得帶着虔誠上路...