Java異常分類和統一處理

一,異常分類

            java異常分爲"檢查"和"非檢查"兩類,"檢查"二字的意思是,代碼編譯時,編譯器會去Check一下有沒有進行異常處理(捕獲或向上拋),對於歸類爲需要檢查的異常,若沒處理,編譯就過不去。
            初學時常常想exception爲啥要這樣分類處理呢? 後來才明白,異常不過兩種:主觀和客觀,一個大多數情況下可以避免,一個大多數情況下無法避免。
            像NullPointerException這類異常,大多跟程序員素質掛鉤(開發好,測試好, 基本不會在系統運行後蹦出來), 基本是可以避免的,java語法當初把它們歸類爲“非檢查”,也算給程序員和編譯器省了不少事。
            而像IOException這類跟外在環境有關的異常,幾乎是不可避免的(指不定哪一天哪一秒網絡就掛了),但是當不期而遇時,程序還是要有所作爲,所以編譯器有必要督促一下程序員,Check一下,看看是否對這些可能不期而至的異常進行了處理。當Exception對象傳遞到某個節點後,程序就可以執行一些必要措施了,比如:給用戶一個友好提示("系統繁忙,請重試")。

二,異常的統一處理

1,服務器處理

下面列舉Tomcat和Nginx爲例

Tomcat是Servlet容器,主要處理動態請求,在web.xml下配置,按http返回碼或Exception類型來處理:

<error-page>
  <error-code>404</error-code>
  <location>/WEB-INF/views/error/404.jsp</location>
 </error-page>
 
 <error-page>
  <error-code>500</error-code>
  <location>/WEB-INF/views/error/500.jsp</location>
 </error-page> 
 
 <error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/WEB-INF/views/error/throwable.jsp</location>
 </error-page>

Nginx,也可以通過Http返回碼很方便地指定異常時的返回頁面:

server {  
    listen 80 ;  
    server_name xx.com ;  
    root /var/www ;  
    index index.html ;  
    error_page 404  /404.html ;  
    location = /404.html {  
       root /usr/share/nginx/html;  
    }  
}  

2,應用程序框架處理

以Spring boot爲例, 在處理接口返回時, 進行全局異常的捕獲

1) 自定義業務異常

/**
 * 自定義業務異常類
 */
public class BusinessException extends RuntimeException {

    private String code;

    public BusinessException(String code, String message) {
        super(message);
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public String getMessage() {
        return super.getMessage();
    }
}

2) 定義接口返回數據結構


/**
 * 接口返回數據對象
 * @param <T> 業務對象
 */
public class Result<T> implements Serializable {
    private String code;
    private String message;
    private T data;

    public Result(String code,String message){
        super();
        this.code=code;
        this.message=message;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

3) 全局捕獲處理


@ControllerAdvice
public class ExceptionController {

    private Logger logger= LoggerFactory.getLogger(ExceptionController.class);

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result exceptionOut(Exception e){
        logger.error("全局異常捕獲,e:{}",e);
        Result result=null;
        if(e instanceof BusinessException){
            result= new Result(((BusinessException) e).getCode(),e.getMessage());
        }else{
            result= new Result("500","系統異常");
        }
        return result;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章