在日常的开发中, 我们很多时候不停的使用 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
来源: http://www.bubuko.com/infodetail-3058268.html