如何優雅的定義統一響應物件

碼農Amg發表於2022-02-14

Hope is being able to see there is light despite all of the darkness

目前主流開發方式都是前後端分離的,定義一種通用統一的返回格式,在前後端進行溝通時是非常有必要的,大家基於這個約定去理解,出現問題能夠快速定位,接下來就介紹一下如何優雅定義統一響應物件

設計統一響應物件

定義一個統一響應物件,這個物件需要完成的事情有

  • 有一個響應狀態碼
  • 有一個響應訊息串
  • 有一個泛型的資料攜帶體
  • 還可以定義一個方法,用來標識當前物件傳遞是否出錯

以下是我習慣使用的,僅供參考

//省略getter和setter等
public class ApiResult<T> {
	/**
	 * 狀態標識
	 */
	private Integer code;
	/**
	 * 攜帶的資訊
	 */
	private String msg;
	/**
	 * 攜帶資料體
	 */
	private T data;
	
	/**
	 * 是否出錯
	 * @return	true or false
	 */
	public boolean isError() {
		return code != HttpStatus.OK.value();
	}
}

由於每次new物件返回,顯得不是很優雅,所以我還會使用到一個輔助的生成類,專門用來快速簡便的生成響應物件

public class ApiResultGenerator {
	
	private static final Integer OK = 200;
	
	private static final Integer SERVER_ERROR = 500;
	
	private static final Integer NOT_FOUND = 404;
	
	public static ApiResult success() {
		ApiResult result = new ApiResult();
		result.setCode(OK);
		return result;
	}
	
	public static <T> ApiResult<T> success(T data) {
		ApiResult<T> result = new ApiResult<>();
		result.setCode(OK);
		result.setData(data);
		return result;
	}
	
	public static ApiResult failure() {
		ApiResult result = new ApiResult();
		result.setCode(SERVER_ERROR);
		result.setMsg("server error...");
		return result;
	}
	
	public static ApiResult failure(String msg) {
		ApiResult result = new ApiResult();
		result.setCode(SERVER_ERROR);
		result.setMsg(msg);
		return result;
	}
	
	public static <T> ApiResult<T> failure(String msg, T data) {
		ApiResult<T> result = new ApiResult();
		result.setCode(SERVER_ERROR);
		result.setMsg(msg);
		result.setData(data);
		return result;
	}
	
	//...自由發揮
}

既然統一響應物件已經建立了,按照我們的習慣就是開始測試了

/**
	 * 返回不攜帶data的(成功例子)
	 * @return
	 */
	public ApiResult getPaperInfoSuccess() {
		if (log.isInfoEnabled()) {
			log.info("收到獲取paper資訊請求...");
		}
		//...業務邏輯
		if (log.isInfoEnabled()) {
			log.info("完成獲取paper資訊請求,準備返回物件資訊");
		}
		return ApiResultGenerator.success();
	}

可以注意,這個json物件就是我們跟前端互動的橋樑,通過isError這個方法可以確定介面是否已經出錯,這個方法同時可以使用在微服務呼叫中

image-20220213232544346

再測試一個失敗的例子

/**
	 * 返回攜帶data的(失敗例子)
	 * @return
	 */
@GetMapping("/getStrSF")
public ApiResult<List<String>> getTestStrFailure() {
    if (log.isInfoEnabled()) {
        log.info("收到獲取Str集合請求...");
    }

    ApiResult<List<String>> response;
    try {
        response = getStrs();
        //手動模擬一個異常
        int i = 1/0;
    } catch (Exception e) {
        if (log.isErrorEnabled()) {
            log.error("獲取Str集合出錯");
        }
        return ApiResultGenerator.failure("獲取Str集合異常", null);
    }
    if (log.isInfoEnabled()) {
        log.info("完成獲取Str集合請求,準備返回物件資訊: {}", JSON.toJSONString(response));
    }
    return response;
}

可以注意到,返回data是null,是因為在返回的時候直接賦值為null了,

image-20220214071332603

相關文章