業務成長記錄:它錯任他錯

向成爲一名不加班的程序員進發,從簡單的開始。前端

怎麼辦,又有報異常?

大佬:你看一下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;
}複製代碼

這樣子就能作大靈活變更。

------------------------------------------------------------------------------------------------

以上就是本次的總結,都是看大佬的代碼,我只是給本身作個總結,學習。謝謝觀看

相關文章
相關標籤/搜索