使用三方jar中的@RestControllerAdvice不起做用

背景

公司封裝了本身的基礎核心包core-base,裏邊包含了Validation的異常捕獲處理類;同時開發項目有全局異常捕獲處理類,經測試發現,core-base裏邊的不起做用html

可能緣由:

  1. 未掃描外部依賴包
  2. 標註@RestControllerAdvice的類,他們會依次加載,遇到異常時,按照類加載順序進行判斷,若是前面的類有能處理這個異常的方法,就給前面的類處理

解決

  1. 使用@ComponentScan()掃描
  2. 設置加載優先級,@Order註解標註或實現Ordered接口,重寫getOrder()方法;
    @Order(Ordered.HIGHEST_PRECEDENCE) // order若是不標註數字,默認最低優先級,由於其默認值是int最大值

經常使用Validation異常處理配置

  • 多個參數校驗時,默認返回全部的錯誤結果,若是隻返回第一個校驗失敗的結果,可經過get(0)獲取第一個,或者經過編寫配置就能夠實現
import com.dangbo.entity.ResultDTO;
import com.dangbo.enums.ResultCode;
import java.util.stream.Collectors;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ValidationExceptionHandler {
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public ResultDTO MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
       List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
       String messages = fieldErrors.stream()
               .map(o -> o.getDefaultMessage())
               .collect(Collectors.joining(","));
       return ResultDTO.error(ResultCode.HTTP_INTERNAL_SERVER_ERROR, messages);
    }

    @ExceptionHandler({BindException.class})
    public ResultDTO BindExceptionHandler(BindException e) {
       List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
       // 多個參數校驗時,默認返回全部的錯誤結果
       String messages = fieldErrors.stream()
               .map(o -> o.getDefaultMessage())
               .collect(Collectors.joining(","));
       return ResultDTO.error(ResultCode.HTTP_INTERNAL_SERVER_ERROR, messages);
    }

    @ExceptionHandler({ConstraintViolationException.class})
    public ResultDTO ConstraintViolationExceptionHandler(ConstraintViolationException e) {
       Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
       String messages = constraintViolations.stream()
               .map(o -> o.getMessage())
               .collect(Collectors.joining(","));
       return ResultDTO.error(ResultCode.HTTP_INTERNAL_SERVER_ERROR, messages);
    }
}

// 通用配置

import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

/**
 * validate參數校驗默認的是一個參數校驗失敗後,還會繼續校驗後面的參數
 * 經過這個配置改爲:校驗參數時只要出現校驗失敗的狀況,就當即拋出對應的異常,結束校驗,再也不進行後續的校驗
 */
@Configuration
public class ValidationConfig {

    @Bean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                .configure()
                //failFast的意思只要出現校驗失敗的狀況,就當即結束校驗,再也不進行後續的校驗。
                .failFast(true)
                .buildValidatorFactory();
        return validatorFactory.getValidator();
    }

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator());
        return methodValidationPostProcessor;
    }
}

參考:https://www.cnblogs.com/chongcheng/p/13058345.htmljava

相關文章
相關標籤/搜索