幫人做網(wǎng)站要怎么賺錢嗎臨沂seo全網(wǎng)營銷
前言
我們?yōu)槭裁匆O(shè)置統(tǒng)一返回響應(yīng)
-
提高代碼的可維護(hù)性:通過統(tǒng)一返回請(qǐng)求的格式,可以使代碼更加清晰和易于維護(hù),減少重復(fù)的代碼,提高代碼質(zhì)量。
-
便于調(diào)試和測試:統(tǒng)一的返回格式使得在調(diào)試和測試時(shí)更為簡單,可以快速定位和解決問題。
-
增強(qiáng)系統(tǒng)的可靠性:統(tǒng)一的返回格式有助于保證系統(tǒng)的穩(wěn)定性和一致性,減少因不同模塊返回格式不統(tǒng)一而導(dǎo)致的錯(cuò)誤。
-
提升用戶體驗(yàn):統(tǒng)一的返回格式使得前端處理更加便捷,提高了響應(yīng)速度,提升了用戶體驗(yàn)。
-
便于日志記錄和監(jiān)控:統(tǒng)一的返回格式便于記錄和監(jiān)控系統(tǒng)的運(yùn)行狀態(tài),方便進(jìn)行故障排查和性能優(yōu)化。
-
簡化前后端接口對(duì)接:前后端約定統(tǒng)一的返回格式后,接口對(duì)接工作會(huì)變得更加順暢,減少溝通成本和開發(fā)時(shí)間。
-
提高擴(kuò)展性:統(tǒng)一的返回格式有利于系統(tǒng)擴(kuò)展,當(dāng)需要新增功能或模塊時(shí),只需遵循既定的返回格式,無需大規(guī)模修改已有代碼。
-
保證數(shù)據(jù)安全:通過統(tǒng)一的返回格式,可以更好地控制返回的數(shù)據(jù)內(nèi)容,避免敏感信息的泄露,提高數(shù)據(jù)安全性。
確定響應(yīng)實(shí)體
我們首先要定義一個(gè)公共的接口響應(yīng)實(shí)體,以后所有的接口返回值,都是返回的這個(gè)公共響應(yīng)實(shí)體。
這樣做的好處是可以統(tǒng)一返回值的風(fēng)格,編譯接口的維護(hù)。
需要包含3個(gè)關(guān)鍵的成員變量:
- 狀態(tài)碼
- 返回信息
- 數(shù)據(jù)
/*** api請(qǐng)求響應(yīng)實(shí)體** @author * @date */
@AllArgsConstructor
@Data
public class ApiResult<T> {/*** 請(qǐng)求成功狀態(tài)碼*/public static final int OK = HttpStatus.HTTP_OK;/*** 接口返回碼*/private int code;/*** 接口返回信息*/private String message;/*** 數(shù)據(jù)*/private T data;
}
確定響應(yīng)實(shí)體工具類
為了更加優(yōu)雅的創(chuàng)建相應(yīng)實(shí)體類,我們可以增加一個(gè)專門的工具類。
這個(gè)工具類的職責(zé)是創(chuàng)建上面的ApiResult類的實(shí)例。
當(dāng)然有兩種情況:
/*** api請(qǐng)求響應(yīng)實(shí)體處理工具類**/
public class ApiResultUtil {private ApiResultUtil() {}/*** 請(qǐng)求成功** @param data 數(shù)據(jù)* @param <T> 數(shù)據(jù)類型* @return 接口相應(yīng)實(shí)體*/public static <T> ApiResult<T> success(T data) {return new ApiResult<>(ApiResult.OK, null, data);}/*** 請(qǐng)求成功** @param <T> 數(shù)據(jù)類型* @return 接口相應(yīng)實(shí)體*/public static <T> ApiResult<T> success() {return success(null);}/*** 請(qǐng)求成功** @param code 返回碼* @param message 返回信息* @param <T> 數(shù)據(jù)類型* @return 接口相應(yīng)實(shí)體*/public static <T> ApiResult<T> error(int code, String message) {return new ApiResult<>(code, message, null);}
}
ApiResultUtil工具類中包含了兩個(gè)重載的success方法,主要是處理接口請(qǐng)求成功的情況。
而error方法,主要是為了處理接口請(qǐng)求出現(xiàn)異常的情況。
需要注意的是ApiResultUtil類有一個(gè)私有的無參構(gòu)造方法,是為了防止調(diào)用者new這個(gè)類的實(shí)例對(duì)象的一種常規(guī)做法,很多JDK源碼中都有類似的做法。
業(yè)務(wù)異常
有了上面公共的響應(yīng)實(shí)體類,我們可以先處理異常了。
但異常有兩種:
- 系統(tǒng)異常
- 業(yè)務(wù)異常
系統(tǒng)異常我們在統(tǒng)一處理時(shí),錯(cuò)誤碼都返回500沒問題。
但如果有些業(yè)務(wù)異常,錯(cuò)誤碼都返回500,這種設(shè)計(jì)不太合理。
因此,我們需要增加一個(gè)專門的業(yè)務(wù)異常類:BusinessException。
AllArgsConstructor
@Data
public class BusinessException extends RuntimeException {public static final long serialVersionUID = -6735897190745766939L;/*** 異常碼*/private int code;/*** 具體異常信息*/private String message;public BusinessException() {super();}
}
這個(gè)異常類繼承了RuntimeException類,是一種運(yùn)行時(shí)異常,后面好處理。
包含了兩個(gè)成員變量:
- code:表示異常碼
- message:表示異常信息
比如用戶添加接口中,出現(xiàn)用戶名稱相同時(shí),異常信息可以提示:用戶名稱重復(fù)。
全局異常處理
接下來,我們可以統(tǒng)一處理全局異常了。
在Spring MVC中可以通過@RestControllerAdvice注解處理全局異常:
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 統(tǒng)一處理異常** @param e 異常* @return API請(qǐng)求響應(yīng)實(shí)體*/@ExceptionHandler(Throwable.class)public ApiResult handleException(Throwable e) {if (e instanceof BusinessException) {BusinessException businessException = (BusinessException) e;log.info("請(qǐng)求出現(xiàn)業(yè)務(wù)異常:", e);return ApiResultUtil.error(businessException.getCode(), businessException.getMessage());}log.error("請(qǐng)求出現(xiàn)系統(tǒng)異常:", e);return ApiResultUtil.error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服務(wù)器內(nèi)部錯(cuò)誤");}
}
正常接口響應(yīng)處理
@ControllerAdvice
public class GlobalApiResultHandler implements ResponseBodyAdvice<Object> {@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = sra.getRequest();String requestURI = request.getRequestURI();return matchUrl(requestURI);}private boolean matchUrl(String uri) {if (StringUtils.isBlank(uri)) {return false;}return uri.contains("/v1");}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if (body instanceof ApiResult) {return (ApiResult) body;}return ApiResultUtil.success(body);}
}