SpringBoot定義全局統一業務異常,且處理filter里面的異常


定義統一異常類:BusinessException.java

package com.miaoying;

import lombok.Data;

@Data
public class BusinessException extends RuntimeException {

    /**
     * 錯誤碼
     */
    private Integer code;

    /**
     * 錯誤信息
     */
    private String message;

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        BusinessException that = (BusinessException) o;

        if (!code.equals(that.code)) return false;
        return message.equals(that.message);

    }

    @Override
    public int hashCode() {
        int result = code != null ? code.hashCode() : 0;
        result = 31 * result + (message != null ? message.hashCode() : 0);
        return result;
    }
}

定義統一的數據返回的結構:ResultResponse<T>.java

package com.miaoying;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultResponse<T> implements Serializable {

    private static final long serialVersionUID = 5261844042861308860L;
    private int retCode;

    private String retMsg;

    private T rsp;

    public static <T> ResultResponse<T> wrapSuccessfulResult(T data) {
        ResultResponse<T> result = new ResultResponse<T>();
        result.rsp = data;
        result.retCode = 200;
        result.retMsg = "ok";
        return result;
    }
}

定義異常攔截器:BusinessExceptionFilter.java

package com.miaoying

import com.miaoying.BusinessException;
import com.miaoying.ResultResponse;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;

@ControllerAdvice
@Slf4j
public class BusinessExceptionFilter {

    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public Object handleBusinessException(HttpServletRequest request, BusinessException ex) {
        log.error("BusinessException code:{},msg:{}", ex.getCode(), ex.getMessage());
        ResultResponse response = new ResultResponse(ex.getCode(), ex.getMessage(), null);
        return JSONObject.toJSON(response);
    }

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object handleException(HttpServletRequest request, Exception ex) {
        log.error("Exception code:{},msg:{}", 500, ex.getMessage());
        ResultResponse response = new ResultResponse(500, "目前業務繁忙,請您稍后!", null);
        return JSONObject.toJSON(response);
    }
}

在需要自定義異常的地方可以直接以如下形式拋出:

throw new BusinessException(503, "異常測試");

可以將錯誤碼、錯誤信息統一管理成常量,總之,還有優化的空間~

使用上述方式,對filter里拋出的異常捕獲不到,所以需要額外處理,如下所示:

@Component
@Slf4j
public class RequestFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        String path = ((HttpServletRequest) servletRequest).getRequestURI();
        if (path.contains("/exception")) {
            throw new BusinessException(401, "filter內部拋出異常");
        }
        filterChain.doFilter(servletRequest, servletResponse);
    }

}

如上代碼所示的filter里面拋出異常,是不會轉換為BusinessException的,而是直接拋出:

所以我采取了一個比較low的方式:直接向頁面response出文字內容(據說可以采用Order改變類的執行順序,進行異常捕獲,但我還沒嘗試過):

  @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        String path = ((HttpServletRequest) servletRequest).getRequestURI();
        try {
            if (path.contains("/exception")) {
                throw new BusinessException(401, "filter內部拋出異常");
            }
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        } catch (Exception e) {
            log.error(e.getMessage());
            ResultResponse response = new ResultResponse();

            if (e instanceof BusinessException) {
                BusinessException be = (BusinessException) e;
                response.setRetCode(be.getCode());
                response.setRetMsg(be.getMessage());
            } else {
                response.setRetCode(500);
                response.setRetMsg(e.getMessage());
            }
            servletResponse.setCharacterEncoding("utf-8");
            servletResponse.getWriter().print(JSONObject.toJSON(response));
            return;

        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM