優(yōu)雅的統(tǒng)一異常處理和全局統(tǒng)一響應(yīng)

全局響應(yīng)支持顯式響應(yīng)和隱式響應(yīng),異常處理支持自定義異常和非自定義異常

廢話不多說(shuō),直接上代碼,優(yōu)雅性,擴(kuò)展性相當(dāng)可以,嘿嘿圖片

代碼結(jié)構(gòu):





Http狀態(tài)碼枚舉類,響應(yīng)的httpcode,最好是統(tǒng)一管理

/**
 * 描述:請(qǐng)求時(shí)的自定義查詢狀態(tài)碼,主要參考Http狀態(tài)碼,但并不完全對(duì)應(yīng) <br>
 * 時(shí)間:2020/7/30 5:15 <br>
 * 作者:老王
 *
 */
public enum HttpCode {
  /** 10系統(tǒng)異常 */
  SYS_EXCEPTION(10),
  /** 200請(qǐng)求成功 */
  OK(200),
  /** 207頻繁操作 */
  MULTI_STATUS(207),
  /** 400請(qǐng)求參數(shù)出錯(cuò) */
  BAD_REQUEST(400),
  /** 401沒(méi)有登錄 */
  UNAUTHORIZED(401),
  /** 4012沒(méi)有登錄-沒(méi)token匹配-登錄超時(shí)*/
  UNAUTHORIZED2(4012),
  /** 4013 用戶被限制登錄*/
  UNAUTHORIZED3(4013),
  /** 4014沒(méi)有登錄-沒(méi)token匹配-異地登錄*/
  UNAUTHORIZED4(4014),
  /** 402登錄失敗 */
  LOGIN_FAIL(402),
  /** 403沒(méi)有權(quán)限 */
  FORBIDDEN(403),
  /** 404找不到頁(yè)面 */
  NOT_FOUND(404),
  /** 405請(qǐng)求方法不能被用于請(qǐng)求相應(yīng)的資源 */
  METHOD_NOT_ALLOWED(405),
  /** 406內(nèi)容特性不滿足 */
  NOT_ACCEPTABLE(406),
  /** 408請(qǐng)求超時(shí) */
  REQUEST_TIMEOUT(408),
  /** 409發(fā)生沖突 */
  CONFLICT(409),
  /** 410已被刪除 */
  GONE(410),
  /** 411沒(méi)有定義長(zhǎng)度 */
  LENGTH_REQUIRED(411),
  /** 412條件不滿足 */
  PRECONDITION_FAILED(412),
  /** 413數(shù)據(jù)太大 */
  ENTITY_TOO_LARGE(413),
  /** 415不是服務(wù)器中所支持的格式 */
  UNSUPPORTED_MEDIA_TYPE(415),
  /** 421連接數(shù)過(guò)多 */
  TOO_MANY_CONNECTIONS(421),
  /** 423已被鎖定 */
  LOCKED(423),
  /** 451法律不允許 */
  UNAVAILABLE_LEGAL(451),
  /** 500服務(wù)器出錯(cuò) */
  SERVER_ERROR(500),
  /** 503服務(wù)器升級(jí)中,暫時(shí)不可用 */
  SERVICE_UNAVAILABLE(503),
  /** 501獲取資源所需要的策略并沒(méi)有被滿足 */
  NOT_EXTENDED(510);
 

  public final Integer code;

  private HttpCode(Integer code) {
    this.code = code;
  }

  /**
   * Return the integer value of this status code.
   */
  public Integer code() {
    return this.code;
  }

  @Override
    public String toString() {
    return this.code.toString();
  }
}
json轉(zhuǎn)化輔助類JsonUtil處理json和對(duì)象/列表/map之間的轉(zhuǎn)換

package com.utils;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
/**
 * @author 老王
 * @date 2018/12/24 11:21 上午
 */
public class JsonUtil {

    public static final ObjectMapper OBJECT_MAPPER = createObjectMapper();
    /**
     * 初始化ObjectMapper
     * @return
     */
    private static ObjectMapper createObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
        // 允許序列化空的POJO類(否則會(huì)拋出異常)
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 對(duì)象的所有字段全部列入。NON_NULL:不返回 null 值字段
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        // 取消java.util.Date, Calendar默認(rèn)轉(zhuǎn)換timestamps形式
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS , false);
        objectMapper.registerModule(new JavaTimeModule());
        // 指定要序列化的域,field,get和set,以及修飾符范圍,ANY是都有包括private和public
        objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);
        return objectMapper;
    }

    public static String object2Json(Object o) {
        StringWriter sw = new StringWriter();
        JsonGenerator gen = null;
        try {
            gen = new JsonFactory().createGenerator(sw);
            OBJECT_MAPPER.writeValue(gen, o);
        } catch (IOException e) {
            throw new RuntimeException("不能序列化對(duì)象為Json", e);
        } finally {
            if (null != gen) {
                try {
                    gen.close();
                } catch (IOException e) {
                    throw new RuntimeException("不能序列化對(duì)象為Json", e);
                }
            }
        }
        return sw.toString();
    }

    /**
     * 對(duì)象轉(zhuǎn)map
     * @param o 轉(zhuǎn)行對(duì)象
     * @return
     */
    public static Map<String, Object> object2Map(Object o) {
        return OBJECT_MAPPER.convertValue(o,Map.class);
    }

    /**
     * map轉(zhuǎn)java對(duì)象
     * @param map 參數(shù)map
     * @param clazz T字節(jié)對(duì)象
     * @param <T> 返回對(duì)象類型
     * @return
     */
    public static <T> T map2Object(Map map, Class<T> clazz) {
        return OBJECT_MAPPER.convertValue(map,clazz);
    }


    /**
     * 將 json 字段串轉(zhuǎn)換為 對(duì)象.
     *
     * @param json  字符串
     * @param clazz 需要轉(zhuǎn)換為的類
     * @return
     */
    public static <T> T json2Object(String json, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (IOException e) {
            throw new RuntimeException("將 Json 轉(zhuǎn)換為對(duì)象時(shí)異常,數(shù)據(jù)是:" + json, e);
        }
    }

    /**
     *   將 json 字段串轉(zhuǎn)換為 List.
     * @param json
     * @param clazz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<T> json2List(String json,Class<T> clazz) throws IOException {
        JavaType type = OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz);
        return OBJECT_MAPPER.readValue(json, type);
    }


    /**
     *  將 json 字段串轉(zhuǎn)換為 數(shù)據(jù).
     * @param json
     * @param clazz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T>  T[] json2Array(String json,Class<T[]> clazz) throws IOException {
        return OBJECT_MAPPER.readValue(json, clazz);

    }

    public static <T> T node2Object(JsonNode jsonNode, Class<T> clazz) {
        try {
            T t = OBJECT_MAPPER.treeToValue(jsonNode, clazz);
            return t;
        } catch (JsonProcessingException e) {
            throw new RuntimeException("將 Json 轉(zhuǎn)換為對(duì)象時(shí)異常,數(shù)據(jù)是:" + jsonNode.toString(), e);
        }
    }

    public static JsonNode object2Node(Object o) {
        try {
            if(o == null) {
                return OBJECT_MAPPER.createObjectNode();
            } else {
                return OBJECT_MAPPER.convertValue(o, JsonNode.class);
            }
        } catch (Exception e) {
            throw new RuntimeException("不能序列化對(duì)象為Json", e);
        }
    }

    /**
     * JsonNode轉(zhuǎn)換為Java泛型對(duì)象,可以是各種類型。
     *
     * @param <T>
     * @param json String
     * @param tr TypeReference,例如: new TypeReference< List<FamousUser> >(){}
     * @return List對(duì)象列表
     */
    public static <T> T json2GenericObject(String json, TypeReference<T> tr) {
        if (json == null || "".equals(json)) {
            throw new RuntimeException("將 Json 轉(zhuǎn)換為對(duì)象時(shí)異常,數(shù)據(jù)是:" + json);
        } else {
            try {
                return (T) OBJECT_MAPPER.readValue(json, tr);
            } catch (Exception e) {
                throw new RuntimeException("將 Json 轉(zhuǎn)換為對(duì)象時(shí)異常,數(shù)據(jù)是:" + json, e);
            }
        }
    }

}

自定義的異常類






package com.http.exception;

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

/**
 * 描述: 基礎(chǔ)異常 <br>
 * 時(shí)間: 2020-02-07 16:18  <br>
 * 作者:老王
 */
public class BaseException extends RuntimeException {
    private int code;
    private String message;
    public BaseException() {
    }
    public BaseException(int code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }
    public BaseException(String msg, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(msg, cause, enableSuppression, writableStackTrace);
    }

    public BaseException(String message, Throwable cause) {
        super(message, cause);
    }

    public BaseException(String message) {
        super(message);
    }

    public BaseException(Throwable cause) {
        super(cause);
    }

    public static String getStackTrace(Throwable throwable) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        throwable.printStackTrace(pw);
        return sw.getBuffer().toString();
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "BaseException{" +
                "code=" + code +
                ", msg='" + message + '\'' +
                '}';
    }
}
package com.http.exception;


import com.http.constant.HttpCode;

/**
 * 描述: 業(yè)務(wù)異常 <br>
 * 時(shí)間: 2020-02-07 16:18  <br>
 * 作者:老王
 */
public class BusinessException extends BaseException {
    private int code = HttpCode.SERVER_ERROR.code;
    private String message;
    public BusinessException() {
    }

    public BusinessException(int code, String message) {
        super(code, message);
        this.code = code;
        this.message = message;
    }

    public BusinessException(Throwable ex) {
        super(ex);
    }

    public BusinessException(String message) {
        this(HttpCode.SERVER_ERROR.code, message);
    }

    public BusinessException(String msg, Throwable ex) {
        super(msg, ex);
    }

    @Override
    public int getCode() {
        return code;
    }

    @Override
    public void setCode(int code) {
        this.code = code;
    }

    @Override
    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
package com.http.exception;

/**
 * 描述: BusinessException業(yè)務(wù)異常描述 <br>
 * 時(shí)間: 2020-02-24 15:16  <br>
 * 作者:老王
 */
public enum BEMsg {
    user_login_name_exist("登錄名已存在"),
    login_user_error("用戶名不存在或密碼錯(cuò)誤"),
    vote_repeat("您已點(diǎn)贊過(guò)"),
    no_auth_error("您無(wú)權(quán)進(jìn)行當(dāng)前操作"),
    no_Sign_error("請(qǐng)登錄后再進(jìn)行當(dāng)前操作"),
    ;

    public String message;

    BEMsg(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

下面就是統(tǒng)一響應(yīng)和處理的代碼

全局結(jié)果響應(yīng)實(shí)體Result

package com.http.response;

import java.io.Serializable;

/**
 * 全局結(jié)果響應(yīng)實(shí)體 <br>
 * 作者:老王 <br>
 * 時(shí)間:2019-01-24 10:33
 */
public class Result<T> implements Serializable {
    /**響應(yīng)的code碼*/
    private int code;
    /**響應(yīng)的success布爾值*/
    private boolean success;
    /**響應(yīng)的message*/
    private String msg;
    /**響應(yīng)的業(yè)務(wù)數(shù)據(jù)*/
    private T data;

    public Result(int code, String msg, T data){
        this.code=code;
        this.msg=msg;
        this.data=data;
    }

    public Result(int code, boolean success, String msg, T data) {
        this.code = code;
        this.success = success;
        this.msg = msg;
        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;
    }

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

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }
}


響應(yīng)的狀態(tài)枚舉

package com.http.response;

/**
 * 描述: 響應(yīng)狀態(tài)枚舉 <br>
 * 時(shí)間: 2020-01-25 19:33  <br>
 * 作者:老王
 */
public enum  ResponseStateEnum {
    success("success"),
    error("error");
    public String value;

    ResponseStateEnum(String state) {
        this.value = state;
    }

    ResponseStateEnum() {
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

全局結(jié)果響應(yīng)建造者,方便構(gòu)建result對(duì)象

package com.http.response;


import com.http.constant.HttpCode;

/**
 * 全局結(jié)果響應(yīng)建造者 <br>
 * 作者:老王 <br>
 * 時(shí)間:2019-01-24 10:33
 */
public class ResultBuilder {

    //自定義message 失敗信息
    public static <T> Result<T> err (String message) {
        return new Result<T>(HttpCode.SERVER_ERROR.code,false, message,null);
    }
    //自定義message 失敗信息
    public static <T> Result<T> err (String message, T data) {
        return new Result<T>(HttpCode.SERVER_ERROR.code, false, message, data);
    }
    //自定義message 失敗信息
    public static <T> Result<T> ok (String message) {
        return new Result<T>(HttpCode.OK.code, true, message,null);
    }
    //自定義message 成功
    public static <T> Result<T> ok (String message, T data) {
        return new Result<T>(HttpCode.OK.code,true, message, data);
    }
    //自定義code,msg 返回?cái)?shù)據(jù)
    public static <T> Result<T> render(int code, boolean success, String msg) {
        return new Result<T>(code, success, msg,null);
    }
    //自定義code,msg,data 返回?cái)?shù)據(jù)
    public static <T> Result<T> render(int code, boolean success, String msg, T data) {
        return new Result<T>(code, success, msg, data);
    }
}



全局結(jié)果異常響應(yīng)實(shí)體,本質(zhì)和Result一樣,只是單獨(dú)處理異常的數(shù)據(jù)響應(yīng)結(jié)構(gòu)

package com.http.response;
/**
 * 全局結(jié)果異常響應(yīng)實(shí)體<br>
 * 作者:老王 <br>
 * 時(shí)間:2019-01-24 10:33
 */
public class ResultException {
    /**響應(yīng)碼*/
    private int code;
    private boolean success = false;
    /**響應(yīng)消息提醒*/
    private String msg;
    /**請(qǐng)求的異常路徑*/
    private String url;

    public ResultException(int code, String msg, String url) {
        this.code = code;
        this.msg = msg;
        this.url = url;
    }

    public ResultException(int code, boolean success, String msg, String url) {
        this.code = code;
        this.success = success;
        this.msg = msg;
        this.url = url;
    }

    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 String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }
}

全局結(jié)果響應(yīng)處理,全局異常處理

package com.http.response;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.http.constant.HttpCode;
import com.http.exception.BusinessException;
import com.utils.JsonUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import javax.servlet.http.HttpServletRequest;

/**
 * 全局結(jié)果響應(yīng)處理,全局異常處理 <br>
 * 作者:老王 <br>
 * 時(shí)間:2019-01-24 10:33
 */
@Slf4j
@RestControllerAdvice
public class ResultAdvice implements ResponseBodyAdvice<Object> {


    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    /**
     * 響應(yīng)前重寫(xiě)處理
     * @param o                     方法響應(yīng)返回實(shí)體
     * @param methodParameter       方法參數(shù)
     * @param mediaType
     * @param aClass
     * @param serverHttpRequest      request
     * @param serverHttpResponse     response
     * @return Object        -       重寫(xiě)方法響應(yīng)返回實(shí)體后的對(duì)象
     */
    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        return builderResult(o);
    }

    /**
     * 重寫(xiě)方法返回對(duì)象響應(yīng)結(jié)構(gòu)
     * @param o
     * @return
     */
    private Object builderResult(Object o) {
        //如果響應(yīng)體Result,直接返回,不做處理
        if (o instanceof Result) {
            return o;
        }
        //返回?cái)?shù)據(jù)data是String的時(shí)候需要做出處理,不然會(huì)報(bào)錯(cuò)
        if (o instanceof String) {
            Result<String> result = ResultBuilder.ok(ResponseStateEnum.success.value, o.toString());
            return JsonUtil.object2Json(result);
        }
        //返回的數(shù)據(jù)若是異常返回信息,那么不做處理直接返回
        if (o instanceof ResultException) {
            return o;
        }
        return ResultBuilder.ok(ResponseStateEnum.success.value, o);
    }

    /**
     * 先捕獲異常 然后再把數(shù)據(jù)返回到ResponseBody中,
     * 然后在Body中要返回?cái)?shù)據(jù)的時(shí)候調(diào)用上面的攔截方法beforeBodyWrite()
     */
    @ExceptionHandler(value = Exception.class)
    public Object handleException(Exception e, HttpServletRequest request) {
        //此處返回json數(shù)據(jù)
        //捕捉到的異常如果是自定義異常類,那么就返回自定義異常類中的錯(cuò)誤碼和錯(cuò)誤信息
        String stackExceptionMsg = ExceptionUtil.stacktraceToString(e);
        //異常輸出到日志
        log.error(stackExceptionMsg);
        //自定義基礎(chǔ)異常
        if (e instanceof BusinessException) {
            return new ResultException(((BusinessException) e).getCode(), false, ((BusinessException) e).getMessage(), request.getRequestURL().toString());
            //非法參數(shù)異常
        } else if (e instanceof IllegalArgumentException) {
            return new ResultException(HttpCode.BAD_REQUEST.code, false, "參數(shù)異常,請(qǐng)稍候再試", request.getRequestURL().toString());
            //綁定異常
        } else if (e instanceof BindException) {
            return new ResultException(HttpCode.BAD_REQUEST.code, false, ((BindException) e).getBindingResult().getFieldError().getDefaultMessage(), request.getRequestURL().toString());
            //方法參數(shù)異常驗(yàn)證異常
        } else if (e instanceof MethodArgumentNotValidException) {
            return new ResultException(HttpCode.BAD_REQUEST.code, false, ((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage(), request.getRequestURL().toString());
        }

        //這里是除了自定義異常的其他異常信息
        else {
            return new ResultException(HttpCode.SERVER_ERROR.code, false, "系統(tǒng)異常請(qǐng)聯(lián)系管理員", request.getRequestURL().toString());
        }
    }
}


這同加了@RestControllerAdvice后,就會(huì)在@RestController的控制器上返回時(shí),對(duì)響應(yīng)結(jié)果進(jìn)行處理重寫(xiě)咯,

流程如下:

@RestController的控制器響應(yīng)后 -->到加了@RestControllerAdvice的ResultAdvice ,在 beforeBodyWrite 方法中重構(gòu)響應(yīng)體Result--> Result由 ResultBuilder 來(lái)構(gòu)建

在@ExceptionHandler(value&#32;=&#32;Exception.class)的方法

handleException上進(jìn)行統(tǒng)一異常處理

hutool的ExceptionUtil控制日志輸出,不然全局異常捕獲,異常日志就無(wú)法輸出,不利于問(wèn)題排查,其他的都是自定義異常和其他異常的統(tǒng)一處理,處理成全局響應(yīng)結(jié)果ResultException,比Result就多了一個(gè)url,之所以這么玩,是因?yàn)椴煌奶幚砦蚁矚g用不同的對(duì)象處理,相互不干擾,但是返回后的json格式還是一樣的,前端可以用一個(gè)對(duì)象就可以接收








下面測(cè)試demo演示

User對(duì)象

package com.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 描述: 用戶model </br>
 * 時(shí)間: 2020-12-14 9:59  </br>
 * 作者:老王
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {

    private Integer id;

    private String userName;

    private Integer age;
}

package com.controller;

import com.http.exception.BaseException;
import com.http.response.Result;
import com.http.response.ResultBuilder;
import com.model.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 描述: 統(tǒng)一結(jié)果響應(yīng)測(cè)試控制器 <br>
 * 時(shí)間: 2022-06-07 8:33  <br>
 * 作者:老王
 */
@RestController
@RequestMapping("/respTest")
public class RespTestController {
    /**
     * 隱式響應(yīng),即方法響應(yīng)體就是業(yè)務(wù)實(shí)體,優(yōu)點(diǎn)直觀明了
     */
    @GetMapping("/getUser")
    public User getUser(){
        User user = new User(1, "IT學(xué)習(xí)道場(chǎng)", 18);
        return user;
    }

    /**
     * 顯式響應(yīng),即方法響應(yīng)體就是result,
     * 優(yōu)點(diǎn)可以自定義一些定制化的響應(yīng)數(shù)據(jù)組裝
     * 但是需要自己構(gòu)建Result對(duì)象
     */
    @GetMapping("/getResult")
    public Result<User> getResult(){
        User user = new User(1, "IT學(xué)習(xí)道場(chǎng)", 18);
        //可以根據(jù)不同的業(yè)務(wù)處理渲染不同的Result,增加了靈活性
        Result<User> result = ResultBuilder.render(200, true, "只是我自己構(gòu)建的Result", user);
        return result;
    }

    /**
     * 測(cè)試統(tǒng)一異常處理(自定義異常)
     */
    @GetMapping("/testBaseException")
    public User testBaseException(){
        throw new BaseException(508, "觸發(fā)自定義業(yè)務(wù)異常了");
    }

    /**
     * 測(cè)試統(tǒng)一異常處理(非自定義異常)
     */
    @GetMapping("/testException")
    public User testException(){
        throw new RuntimeException("業(yè)務(wù)異常了");
    }


}

public User getUser(){} 響應(yīng)Result結(jié)構(gòu)

{
  "code": 200,
  "success": true,
  "msg": "success",
  "data": {
    "id": 1,
    "userName": "IT學(xué)習(xí)道場(chǎng)",
    "age": 18
  }
}


public Result<User> getResult(){} 響應(yīng)Result結(jié)構(gòu)



{
  "code": 200,
  "success": true,
  "msg": "只是我自己構(gòu)建的Result",
  "data": {
    "id": 1,
    "userName": "IT學(xué)習(xí)道場(chǎng)",
    "age": 18
  }
}
public User testBaseException(){} 響應(yīng)Result結(jié)構(gòu)

{
  "code": 500,
  "success": false,
  "msg": "系統(tǒng)異常請(qǐng)聯(lián)系管理員",
  "url": "http://localhost:8080/respTest/testBaseException"
}
public User testException()響應(yīng)Result結(jié)構(gòu)

{
  "code": 500,
  "success": false,
  "msg": "系統(tǒng)異常請(qǐng)聯(lián)系管理員",
  "url": "http://localhost:8080/respTest/testException"
}

作者:老王


歡迎關(guān)注微信公眾號(hào) : IT學(xué)習(xí)道場(chǎng)