1. 程式人生 > 其它 >springmvc學習指南 之---第30篇 異常的全域性處理

springmvc學習指南 之---第30篇 異常的全域性處理

對於異常的處理,現在寫的這個小專案,每次都在呼叫方法加上一個try catch(),上午在寫dongabo商城專案就發現他的呼叫方法時沒有trycatch的,那依據經驗他就是有全域性處理@ControllerAdvice

那麼對於全域性處理的佈局應該怎麼寫呢?這就要依據會出現的異常情況,有以下異常情況

  • 自定義異常 BusinessException
  • 方法引數校驗@NotNull 的校驗異常,分兩種情況一種是Post請求 一種是Get請求
  • 引數json解析異常,比如說DTO中的成員變數型別是Integer,引數中是String,那麼就解析異常,或者 post 請求,沒有攜帶引數

那麼就會對應相應的異常處理

  • 自定義簡單 @ExceptionHandler({BusinessException.class})
  • 方法引數分給POST 用 @ExceptionHandler(MethodArgumentNotValidException.class)
  • 方法引數分配GET,校驗單個引數,用 @ExceptionHandler(HttpMessageConversionException.class)
  • json解析異常使用,@ExceptionHandler(HttpMessageConversionException.class)

那麼就貼上一下dongbao的全域性異常處理程式碼

package com.msb.dongbao.portal.exception;

import com.google.common.collect.Lists;
import com.msb.dongbao.common.
base.dto.ResultWrapper; import com.msb.dongbao.common.base.enums.StateCodeEnum; import com.msb.dongbao.common.base.exception.BusinessException; import lombok.extern.slf4j.Slf4j; import org.springframework.http.converter.HttpMessageConversionException; import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import java.util.List;
/** * 統一異常處理 */ @Slf4j @ControllerAdvice public class GlobalExceptionAdvice { @ResponseBody @ExceptionHandler({BusinessException.class}) public ResultWrapper bizException(BusinessException e) { log.error("出現異常:{}", e); return ResultWrapper.builder().code(e.getErrorCode()).msg(e.getMessage()).build(); } @ResponseBody @ExceptionHandler(MethodArgumentNotValidException.class) public ResultWrapper methodArgumentNotValidException(MethodArgumentNotValidException e) { log.error("出現異常:{}", e); List<ObjectError> errors = e.getBindingResult().getAllErrors(); // 已經設定了快速失敗,可以預設取首個錯誤即可 StringBuffer sb = new StringBuffer(); List<String> errorArr = Lists.newArrayList(); for (ObjectError error : errors) { if (error instanceof FieldError) { FieldError fieldError = (FieldError) error; errorArr.add(fieldError.getField() + fieldError.getDefaultMessage()); } else { errorArr.add(error.getObjectName() + error.getDefaultMessage()); } } String errMsg = String.join(";", errorArr.toArray(new String[]{})); return ResultWrapper.builder().code(StateCodeEnum.METHOD_ARGUMENT_NOT_VALID.getCode()).msg(errMsg).build(); } @ResponseBody @ExceptionHandler(ConstraintViolationException.class) public ResultWrapper constraintViolationException(ConstraintViolationException e) { // 攔截單個引數校驗異常捕獲 log.error("出現異常:{}", e); // @RequestParam 引數校驗失敗 StringBuffer sb = new StringBuffer(); List<String> errorArr = Lists.newArrayList(); for (ConstraintViolation constraint : e.getConstraintViolations()) { errorArr.add(constraint.getInvalidValue() + "非法" + constraint.getMessage()); } String errMsg = String.join(";", errorArr.toArray(new String[]{})); return ResultWrapper.builder().code(StateCodeEnum.CONSTRAINT_VIOLATION.getCode()).msg(errMsg).build(); } @ResponseBody @ExceptionHandler(Exception.class) public ResultWrapper exception(Exception e) { log.error("出現異常:{}", e); return ResultWrapper.builder().code(StateCodeEnum.ERROR.getCode()).msg(e.getMessage()).build(); } /** * 引數錯誤型別轉換 * * @param e * @return */ @ResponseBody @ExceptionHandler(HttpMessageConversionException.class) public ResultWrapper parameterTypeConvertException(HttpMessageConversionException e) { return ResultWrapper.builder().code(StateCodeEnum.ERROR.getCode()).msg(e.getMessage()).build(); } }