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() + "\n");
    }

    ResultVO<Object> vo = initResp();
    vo.setMsg(strBuilder.toString());
    Object resp = vo.build();
    logger.error("Excpetion Handler || Error Response Body: [ {} ]", resp, e);
    return resp;
  }


}


免責聲明!

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



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