import com.ranktech.base.common.ErrorCodeEnum;
import com.ranktech.base.dto.ResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
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;
/**
* 统一异常处理类
* @Author: Mr.chang
*/
@ControllerAdvice
@Slf4j
public class CommonExceptionHandler {
/**
* 拦截Exception类的异常
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public ResultDTO<Object> exceptionHandler(Exception e){
//正常开发中,可创建一个统一响应实体,如CommonResp
return ResultDTO.ok(ErrorCodeEnum.SYS_ERROR.getCode(),e.getMessage());
}
/**
* 拦截参数校验异常
* @param ex
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResultDTO<Object> handleBindException(MethodArgumentNotValidException ex) {
FieldError fieldError = ex.getBindingResult().getFieldError();
log.info("参数校验异常:{}({})", fieldError.getDefaultMessage(),fieldError.getField());
return ResultDTO.ok(ErrorCodeEnum.ILLEGAL_PARAM.getCode(),fieldError.getDefaultMessage());
}
/**
* 拦截必填参数异常
* @param ex
* @return
*/
@ExceptionHandler(BindException.class)
@ResponseBody
public ResultDTO<Object> handleBindException(BindException ex) {
//校验 除了 requestbody 注解方式的参数校验 对应的 bindingresult 为 BeanPropertyBindingResult
FieldError fieldError = ex.getBindingResult().getFieldError();
log.info("必填校验异常:{}({})", fieldError.getDefaultMessage(),fieldError.getField());
return ResultDTO.ok(ErrorCodeEnum.ILLEGAL_PARAM.getCode(),fieldError.getDefaultMessage());
}
}
这里的ResultDTO是我这边自己的一个封装返回方法,建议大家如果自己有封装统一的返回方式,那就继续使用,如果没有的话也可以使用Map方式进行返回
/**
* 拦截Exception类的异常
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public Map<String,Object> exceptionHandler(Exception e){
Map<String,Object> result = new HashMap<String,Object>();
result.put("respCode", "9999");
result.put("respMsg", e.getMessage());
return result;
}
在正常开发中,可创建一个统一响应实体,如CommonResp
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DemoReqDTO {
@NotEmpty(message = "姓名不可为空")
@ApiModelProperty("姓名")
private String id_holder;
}
然后在控制层Controller方法里,加入@Valid即可,这样在访问前,会对请求参数进行检验。
@ApiOperation("测试Demo")
@PostMapping("/v1.0/DemoTest")
public ResultDTO<Object> identityAuthInfow(@RequestBody @Valid DemoReqDTO req) {
return Service.Test(req);
}
postman请求之后就会得到相应的返回错误信息,很方便
这样数据的统一校验就完成了,对于其他注解的使用,大家可自行谷歌下,基本上都很简单的
有什么不足,欢迎大家补充指正