全局异常统一处理
package com.frank.config;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.servlet.http.HttpServletRequest;
@Log4j2
@RestControllerAdvice
public class GlobalExceptionHandler {
@Autowired
private ObjectMapper mapper;
// 参数类型错误
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public <T> Api<T> methodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) {
log.error("接口参数类型异常,路径:{},参数名:{},参数类型:{},参数值:{}",
request.getRequestURI(),
e.getName(),
e.getRequiredType().getSimpleName(),
e.getValue(), e);
return Api.error("参数错误");
}
// @Validated参数校验失败
@ExceptionHandler(BindException.class)
public <T> Api<T> bindExceptionHandler(BindException e, HttpServletRequest request) throws JsonProcessingException {
FieldError fieldError = e.getBindingResult().getFieldError();
log.error("接口参数校验异常,路径:{},入参:{},参数名:{},参数值:{},信息:{}",
request.getRequestURI(),
mapper.writeValueAsString(e.getBindingResult().getTarget()),
fieldError.getField(),
fieldError.getRejectedValue(),
fieldError.getDefaultMessage(), e);
return Api.error(e.getBindingResult().getFieldError().getDefaultMessage());
}
// @RequestBody @Validated参数校验失败
@ExceptionHandler(MethodArgumentNotValidException.class)
public <T> Api<T> methodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) throws JsonProcessingException {
FieldError fieldError = e.getBindingResult().getFieldError();
log.error("接口参数校验异常,路径:{},入参:{},参数名:{},参数值:{},信息:{}",
request.getRequestURI(),
mapper.writeValueAsString(e.getBindingResult().getTarget()),
fieldError.getField(),
fieldError.getRejectedValue(),
fieldError.getDefaultMessage(), e);
return Api.error(fieldError.getDefaultMessage());
}
// @RequestParam参数缺失异常
@ExceptionHandler(MissingServletRequestParameterException.class)
public <T> Api<T> exception(MissingServletRequestParameterException e, HttpServletRequest request) {
log.error("接口参数缺少异常,路径:{},参数名:{},参数类型:{}",
request.getRequestURI(),
e.getParameterName(),
e.getParameterType(), e);
return Api.error("参数错误");
}
@ExceptionHandler(Exception.class)
public <T> Api<T> exception(Exception e, HttpServletRequest request) {
log.error("接口异常,路径:{}", request.getRequestURI(), e);
return Api.error("系统错误");
}
}
校验快速失败设置
@Bean
public Validator validator() {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
//failFast的意思只要出现校验失败的情况,就立即结束校验,不再进行后续的校验。
.failFast(true)
.buildValidatorFactory();
return validatorFactory.getValidator();
}