向成爲一名不加班的程序員進發,從簡單的開始。前端
大佬:你看一下log,這裏報異常了,你怎麼不提醒?java
小糖:哦哦,我把bug改一下。程序員
大佬:不是,你怎麼不提醒有異常。spring
小糖:嗯?編程
剛剛接觸後臺的時候,由於有過Android工做的編程經歷,java還算是順手,編碼工做還算順利。但對於異常,我常作的就是不讓它報出來,封得死死的(小白寫法),一個App報出了異常,必定不讓用戶發現。可是後臺就不是這麼回事了。有了問題必定讓他報錯來,記錄在log裏面看,也要給前端提醒。返回類有返回碼。個人成功返回碼是000000。其餘的返回碼都是異常,無論是查不到改用戶,仍是手機號碼輸入錯誤,這些均可以用來異常來處理。json
所報的異常都是所知道的層,好比沒有該資源,好比,找不到該用戶。雖然他們是能夠按照順利的流程返回到Controller層,可是這麼本能夠在查詢不到該用戶的時候就結束流程,再一步步返回到controller層是否是太浪費了。bash
給出一個規則:在不符合正常路線的流程均可視爲異常。微信
這裏用到了spring的攔截異常處理,經過他返回全部的異常。app
spring中,有一個抽象類,HandlerExceptionResolver能夠攔截到系統中報出的全部異常dom
public class HealthHandlerExceptionResolver implements HandlerExceptionResolver {
public Logger logger = Logger.getLogger(this.getClass());
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) {
}
}複製代碼
全部爆出來的異常都會再次到這個方法來。Exception 這個字段 就是咱們報錯的異常。
而咱們作的就是正確處理這個異常字段
在攔截異常中,是Exception類型,提醒的也天然是這個類型。咱們對這個類進行處理
繼承此類,子類BaseException
public class BaseException extends Exception {
private static final long serialVersionUID = 1L;
private String logMsg;
//錯誤碼 枚舉
private ErrorCode code;
public BaseException(ErrorCode code) {
super();
this.code = code;
}
public BaseException(ErrorCode code,String logMsg,String msg){
super();
this.code = code;
this.code.setMsg(msg);
this.logMsg=logMsg;
}
public BaseException(ErrorCode code,String logMsg) {
super();
this.code = code;
this.logMsg=logMsg;
}
public String getLogMsg() {
return logMsg;
}
public void setLogMsg(String logMsg) {
this.logMsg = logMsg;
}
public ErrorCode getCode() {
return code;
}
public void setCode(ErrorCode code) {
this.code = code;
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
public String parseString() {
//ResponseInfo 是返回類
return JSONObject.toJSONString(new ResponseInfo(code));
}
}複製代碼
錯誤碼的枚舉類
public enum ErrorCode {
companyError("70006+","手機號碼錯誤"),
weChatLoginError("600002","微信登陸異常"),
permissionDenied("900005","沒有權限,拒絕訪問" );
private String code;
private String msg;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
private ErrorCode(String code, String msg) {
this.code = code;
this.msg = msg;
}
}複製代碼
在BaseException類的構造方法中
public BaseException(ErrorCode code) {
super();
this.code = code;
}複製代碼
經過填入對應的錯誤碼,再經過spring的攔截器,識別並返回json
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
String returnInfo=null;
if(ex instanceof TTException) { //識別出對應的異常
logger.info(ex.toString());
returnInfo=((BaseException)ex).parseString(); //返回String類型 json
}else {
logger.error("SystemException!", ex);
returnInfo= "{\"returnCode\":\"999999\",\"returnMsg\":\"系統錯誤\"}";
}
try {
//利用HttpServletResponse 返回
ResponseWriteUtil.writerJSONInfo(returnInfo, response);
} catch (IOException e1) {
e1.printStackTrace();
}
return new ModelAndView();
}複製代碼
給前端輸出數據的方法
public static void writerJSONInfo(String json,HttpServletResponse response) throws IOException {
PrintWriter pw=getWriter(response,"application/json;charset=utf-8");
logger.info("return info is "+json);
pw.print(json);
pw.flush();
pw.close();
}複製代碼
繼承BaseException的的login登陸異常類
public class TTException extends BaseException {
//query_not_found_openId 能夠用作log記錄
public TTException(ErrorCode code, String query_not_found_openId) {
super(code);
}
@Override
public String toString() {
return "LoginException : "+this.getLogMsg();
}
}複製代碼
使用
throw new TTException(ErrorCode.nosuchuser,phone + "未註冊");
{"returnCode":"800001","returnMsg":"手機號碼未被註冊","serialNum":"957c0d76-2d7e-45cd-898c-f49e0d74e6cc"}複製代碼
如今有了新的需求,好比:A用手機號註冊一個身份證,發現被佔用了,要提示出176****被佔用。這個該怎麼辦呢,枚舉類都已經定了版。這個時候,我要作的是對這個提示作一下手腳了。錯誤枚舉類,只要它的錯誤碼,提示類容另外填入。
一樣是實現BaseException的繼承
public class RegisterDulipcaException extends BaseException{
private String msg;
private static final long serialVersionUID = 1L;
public ZCRegisterDulipcaException(ErrorCode code) {
super(code);
}
public ZCRegisterDulipcaException(ErrorCode code,String logMsg,String msg) {
super(code,logMsg);
this.msg=msg; //變更的提示信息
}
//對錯誤數據進行處理
public String parseString() {
ResponseInfo returnResponseInfo=new ResponseInfo(getCode());
returnResponseInfo.setReturnMsg(msg);
return JSONObject.toJSONString(returnResponseInfo);
}
}複製代碼
返回類關於ErrorCode的構造方法
public ResponseInfo(ErrorCode responseCode) {
super();
this.returnCode = responseCode.getCode();
this.returnMsg = responseCode.getMsg();
this.serialNum = UUID.randomUUID().toString();
}複製代碼
修改掉returnMsg
public void setReturnMsg(String returnMsg) {
this.returnMsg = returnMsg;
}複製代碼
這樣子就能作大靈活變更。
------------------------------------------------------------------------------------------------
以上就是本次的總結,都是看大佬的代碼,我只是給本身作個總結,學習。謝謝觀看