需求:小程序登陸時,後臺須要將異常拋出,並將錯誤信息交給前臺。spring
public class WechatLoginException extends RuntimeException { /** * @Description 自定義狀態碼 * 510: 未找到該學號或該學號的狀態已凍結 * 509: 該學號已被其餘微信賬號綁定,請聯繫老師或者管理員解除綁定 * 508: 該微信賬號已綁定學號,請解除綁定後從新登陸 **/ private HttpStatus status = null; public WechatLoginException(String message, HttpStatus httpStatus) { super(message); status = httpStatus; } public HttpStatus getStatus() { return status; } }
if (student.getWechat() != null && !student.getWechat().getOpenid().equals(openId)) { throw new WechatLoginException("該學號已被其餘微信賬號綁定,請聯繫老師或者管理員解除綁定", HttpStatus.valueOf(509)); }
// 處理微信登陸的異常 @ExceptionHandler(WechatLoginException.class) public ResponseEntity<JsonErrorResult> wechatLoginHandler(HttpServletRequest request, WechatLoginException e){ logger.error("微信登陸異常:---Host {} invokes url {} ERROR: {}", request.getRemoteHost(), request.getRequestURL(), e.getMessage()); return new ResponseEntity<>(new JsonErrorResult(request, e), e.getStatus()); }
後來,潘老師和張喜碩學長評論說這樣寫很差,由於開放異常信息
,異常的狀態碼只靠註釋約束,當返回未知狀態碼前臺不知道如何處理。小程序
根據潘老師的建議,作出以下修改:微信
public enum HttpStatusEnum { StudentNotFound("未找到該學生", 601), StudentIsForzen("該學生的狀態已凍結", 602), StudentISBinded("該學號已被其餘微信賬號綁定,請聯繫老師或者管理員解除綁定", 603), WecahtIsBinded("該微信賬號已綁定學號,請解除綁定後從新登陸", 604); private String description; private int code; private HttpStatusEnum (String description, int code) { this.description = description; this.code = code; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } }
public class WechatLoginException extends RuntimeException { private int code; // 異常狀態碼 public WechatLoginException(HttpStatusEnum httpStatusEnum) { super(httpStatusEnum.getDescription()); code = httpStatusEnum.getCode(); } public int getCode() { return code; } }
throw new WechatLoginException(HttpStatusEnum.StudentISBinded);
//處理微信登陸的異常 @ExceptionHandler(WechatLoginException.class) public ResponseEntity<JsonErrorResult> wechatLoginHandler(HttpServletRequest request, WechatLoginException e){ logger.error("微信登陸異常:---Host {} invokes url {} ERROR: {}", request.getRemoteHost(), request.getRequestURL(), e.getMessage()); return new ResponseEntity<>(new JsonErrorResult(request, e), e.getStatus()); }
而後這一步就出現了問題,使用ResponseEntity返回異常信息時,第二個參數須要傳入HttpStatus,如圖:spring-boot
而張喜碩學長指出,spring-boot的HttpStatus枚舉是不可擴展的,即我沒法經過繼承來增長自定義的http狀態碼測試
因此,此時陷入一個僵局,要麼放棄使用自定義狀態碼,要麼放棄使用ResponseEntity,這時,張喜碩學長說了一下他的解決方案,即不返回ResponseEntity了,而是注入HttpServletResponse,調取setStatus()直接改返回的狀態碼:this
// 處理微信登陸的異常 @ExceptionHandler(value = WechatLoginException.class) public String WechatLoginExceptionHandler(HttpServletRequest request, HttpServletResponse response, WechatLoginException e) throws IOException { logger.error("微信登陸異常:---Host {} invokes url {} ERROR: {}", request.getRemoteHost(), request.getRequestURL(), e.getMessage()); response.setStatus(e.getCode()); return e.getMessage(); }
而後在小程序端測試,發現果真狀態碼能夠變成了自定義的了
接着,就是在小程序端添加異常處理:url
public static handleHttpException(response: RequestSuccessCallbackResult) { let result = ''; switch (response.statusCode) { case 601: result = '未找到該學生'; break; case 602: result = '該學生的狀態已凍結'; break; case 603: result = '該學號已被其餘微信賬號綁定,請聯繫老師或者管理員解除綁定'; break; case 604: result = '該微信賬號已綁定學號,請解除綁定後從新登陸'; } // 若是異常信息不爲空,則顯示提示信息,而且拋出異常 if (result != '') { // 顯示異常 wx.showToast({ title: result, icon: "none", duration: Request.duration }); throw response; } }
最後的效果:spa
總得來講,此次收穫仍是挺多的,遇到了很多問題,也對一些知識的盲區進行了探索和挖掘。雖然實現了需求,但以爲小程序的異常處理仍是有些生硬
,還有改進的餘地。code