zoukankan      html  css  js  c++  java
  • SpringMVC统一异常处理

    SpringMVC统一异常处理

    在开发中,不管是dao层、service层还是controller层,都有可能抛出异常,在springmvc中,能将所有类型的异常处理从各处理过程解耦出来,既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护。我总结SpringMVC中统一处理异常的两种常见方式。

    使用@ ExceptionHandler 注解

    @Controller      
    public class GlobalController {               
    
       /**    
         * 用于处理异常的    
         * @return    
         */      
        @ExceptionHandler({MyException.class})       
        public String exception(MyException e) {       
            System.out.println(e.getMessage());       
            e.printStackTrace();       
            return "exception";       
        }       
    
        @RequestMapping("test")       
        public void test() {       
            throw new MyException("出错了!");       
        }                    
    }
    

    可以看到,这种方式最大的缺陷就是不能全局控制异常。每个Controller类都要写一遍。当然还可以通过继承的方式,进行优化。这样只需要写一个父类,其他Controller继承这个父类。

    public class AbstractController {
    
        @ExceptionHandler(BizException.class)
        @ResponseBody
        public Response<?> handleException(BizException ex) {
            log.error(Utils.getExceptionInfo(ex, Utils.KERY_PACKAGE_PRE, 1));
            Response response = ex.getResponse();
            response.setMessageId(MDCUtils.getMsgId());
            return response;
        }
    
        @ExceptionHandler(DuplicateKeyException.class)
        @ResponseBody
        public Response<?> handleException(DuplicateKeyException ex) {
            Response<?> response = new Response<>(CodeMessage.DATA_ERROR);
            logError(response, ex);
            return response;
        }
    }
    

    使用 @ControllerAdvice 注解

    @ControllerAdvice,这是 Spring 3.2 带来的新特性。 使用@controlleradvice + @ ExceptionHandler 也可以实现全局的异常捕捉。

    public class BusinessExceptionControllerAdvice {
      private Logger logger = LoggerFactory.getLogger("ErrorFile");
    
    
    
      public ResultVO<Object> initResp() {
        ResultVO<Object> vo = new ResultVO<>();
        vo.setStatus(Status.FAIL.getCode());
        vo.setMsg(Status.FAIL.getMessageKey());
        return vo;
      }
    
      /**
       * 业务异常
       *
       * @param exception
       * @return
       */
      @ExceptionHandler(BusinessException.class)
      @ResponseBody
      @ResponseStatus(value = HttpStatus.OK)
      public Object businessErrorHandler(BusinessException exception) {
        ResultVO<Object> vo = initResp();
        vo.setStatus(exception.getErrorCode().getCode());
        vo.setMsg(StringUtils.isEmpty(exception.getErrorMsg()) ? exception.getErrorCode().getMsg()
            : exception.getErrorMsg());
    
        Object resp = vo.build();
        logger.error("Excpetion Handler || Error Response Body: [ {} ]", resp, exception);
    
        return resp;
      }
    
      /**
       * Spring validation
       *
       * @param e
       * @return
       */
      @ExceptionHandler(value = {ConstraintViolationException.class})
      @ResponseStatus(value = HttpStatus.OK)
      public Object validException(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        StringBuilder strBuilder = new StringBuilder();
        for (ConstraintViolation<?> violation : violations) {
          strBuilder.append(violation.getMessage() + "
    ");
        }
    
        ResultVO<Object> vo = initResp();
        vo.setMsg(strBuilder.toString());
        Object resp = vo.build();
        logger.error("Excpetion Handler || Error Response Body: [ {} ]", resp, e);
        return resp;
      }
    
    
    }
    
  • 相关阅读:
    jeecg团队招新人(5人)
    编程之美2.14 求数组的子数组之和的最大值
    使用VS连接SQLServe时提示未能载入文件或程序集“System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKey
    Drupal 7.31 SQL注入漏洞利用具体解释及EXP
    linux下mysql开启慢查询
    答大二学生:坚持正确方向,改变学习方式
    JavaWeb-10(会话技术之session&amp;JSP)
    Java内存区域分析
    Linux系统编程——进程间通信:命名管道(FIFO)
    学科、专业目录_各类名单_中国学位与研究生教育信息网
  • 原文地址:https://www.cnblogs.com/lanqi/p/8515721.html
Copyright © 2011-2022 走看看