springboot 使用@ControllerAdvice注解全局處理系統異常


轉自:https://blog.51cto.com/chenhva/2394065

在日常的開發中,我們很多時候不停的使用try catch來處理異常,這樣的代碼重復性強,通過@controllerAdvice 注解來實現可以全局定義異常,大大減少代碼的try catch。

import com.vicrab.api.bean.OperateCode;
import com.vicrab.api.server.model.OperateResult;
import org.apache.shiro.authc.AuthenticationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;

@ControllerAdvice
public class ControllerExceptionHandler {

private static final Logger logger = LoggerFactory.getLogger(ControllerExceptionHandler.class); private static final String logExceptionFormat = "Capture Exception By GlobalExceptionHandler: Code: %s Detail: %s"; //運行時異常 @ExceptionHandler(RuntimeException.class) @ResponseBody public OperateResult runtimeExceptionHandler(RuntimeException ex) { return exceptionFormat(OperateCode.EX_RUN, ex); } //空指針異常 @ExceptionHandler(NullPointerException.class) @ResponseBody public OperateResult nullPointerExceptionHandler(NullPointerException ex) { return exceptionFormat(OperateCode.EX_NULL, ex); } //類型轉換異常 @ExceptionHandler(ClassCastException.class) @ResponseBody public OperateResult classCastExceptionHandler(ClassCastException ex) { return exceptionFormat(OperateCode.EX_CAST, ex); } //IO異常 @ExceptionHandler(IOException.class) @ResponseBody public OperateResult iOExceptionHandler(IOException ex) { return exceptionFormat(OperateCode.EX_IO, ex); } //未知方法異常 @ExceptionHandler(NoSuchMethodException.class) @ResponseBody public OperateResult noSuchMethodExceptionHandler(NoSuchMethodException ex) { return exceptionFormat(OperateCode.EX_NO_SUCH_METHOD, ex); } //數組越界異常 @ExceptionHandler(IndexOutOfBoundsException.class) @ResponseBody public OperateResult indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) { return exceptionFormat(OperateCode.EX_INDEX_OUT_OF_BOUNDNS, ex); } //400錯誤 @ExceptionHandler({HttpMessageNotReadableException.class}) @ResponseBody public OperateResult requestNotReadable(HttpMessageNotReadableException ex) { logger.error("400..requestNotReadable"); return exceptionFormat(OperateCode.BAD_REQUEST, ex); } //400錯誤 @ExceptionHandler({TypeMismatchException.class}) @ResponseBody public OperateResult requestTypeMismatch(TypeMismatchException ex) { logger.error("400..TypeMismatchException"); return exceptionFormat(OperateCode.BAD_REQUEST, ex); } //400錯誤 @ExceptionHandler({MissingServletRequestParameterException.class}) @ResponseBody public OperateResult requestMissingServletRequest(MissingServletRequestParameterException ex) { logger.error("400..MissingServletRequest"); return exceptionFormat(OperateCode.BAD_REQUEST, ex); } //405錯誤 @ExceptionHandler({AuthenticationException.class}) @ResponseBody public OperateResult request401(AuthenticationException ex) { return exceptionFormat(OperateCode.UNAUTHORIZED, ex); } //405錯誤 @ExceptionHandler({HttpRequestMethodNotSupportedException.class}) @ResponseBody public OperateResult request405(HttpRequestMethodNotSupportedException ex) { return exceptionFormat(OperateCode.METHOD_NOT_ALLOWED, ex); } //406錯誤 @ExceptionHandler({HttpMediaTypeNotAcceptableException.class}) @ResponseBody public OperateResult request406(HttpMediaTypeNotAcceptableException ex) { logger.error("406..."); return exceptionFormat(OperateCode.NOT_ACCEPTABLE, ex); } //500錯誤 @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class}) @ResponseBody public OperateResult server500(RuntimeException ex) { logger.error("500..."); return exceptionFormat(OperateCode.INTERNAL_SERVER_ERROR, ex); } //棧溢出 @ExceptionHandler({StackOverflowError.class}) @ResponseBody public OperateResult requestStackOverflow(StackOverflowError ex) { return exceptionFormat(OperateCode.EX_STACK_OVER_FLOW, ex); } //其他錯誤 @ExceptionHandler({Exception.class}) @ResponseBody public OperateResult exception(Exception ex) { return exceptionFormat(OperateCode.EX_OTHER, ex); } private <T extends Throwable> OperateResult exceptionFormat(OperateCode operateCode, T ex) { logger.error(String.format(logExceptionFormat, operateCode, ex)); return OperateResult.exception(operateCode, ex); }

}

@ExceptionHandler 用來定義異常的類型,這里面列舉了空指針異常等,其實還可以實現自定義異常,比如

public class MyException extends RuntimeException {

public MyException(String code, String msg) { this.code = code; this.msg = msg; } private String code; private String msg; // getter & setter

}

import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@ControllerAdvice
public class MyControllerAdvice {

/** * 全局異常捕捉處理 * @param ex * @return */ @ResponseBody @ExceptionHandler(value = Exception.class) public Map errorHandler(Exception ex) { Map map = new HashMap(); map.put("code", 100); map.put("msg", ex.getMessage()); return map; } @ResponseBody @ExceptionHandler(value = MyException.class) public Map myErrorHandler(MyException ex) { Map map = new HashMap(); map.put("code", ex.getCode()); map.put("msg", ex.getMsg()); return map; }

}

controller中拋出異常進行測試。

@RequestMapping("/home")
public String home() throws Exception {

// throw new Exception("Sam 錯誤");
throw new MyException("101", "Sam 錯誤");

}

啟動應用,訪問:http://localhost:8080/home


免責聲明!

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



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