SpringBoot使用validation-api实现参数校验的示例
我们在开发Java项目的时候,经常需要对参数进行一些必填项、格式、长度等进行校验,如果手写代码对参数校验,每个接口会需要很多低级的代码,这样会降低代码的可读性。那么我们能不能使用一种比较优雅的方式来实现,对请求中的参数进行校验呢?
knife4j的安装与使用可参考我的博客:SpringBoot使用knife4j进行在线接口调试
正文
ValidationApi框架就是用来解决参数校验中代码冗余问题,ValidationApi框架提供一些注解用来帮助我们对请求参数进行校验:
SpringBoot使用validation-api实现参数校验
注入依赖
javax.validation validation-api 2.0.1.Final org.apache.commons commons-lang3 3.3.2 org.projectlombok lombok 1.18.2 true com.github.xiaoymin knife4j-spring-boot-starter 2.0.4
UserPojoReq.java请求封装类
如果成员变量是其他对象实体,该变量必须加@Valid,否则嵌套中的验证不生效
@Setter
@Getter
@ToString
@ApiModel("用户对象")
publicclassUserPojoReqextendsRequestimplementsSerializable{
privatestaticfinallongserialVersionUID=-354657839724457905L;
@ApiModelProperty(required=true,notes="主键",example="123")
privateStringid;
@ApiModelProperty(required=true,notes="用户名",example="luo")
@NotNull(message="用户姓名为必填项,不得为空")
@Size(min=2,max=20,message="用户名长度要在2—8个字符")
privateStringname;
@ApiModelProperty(required=true,notes="消息",example="消息")
privateStringmsg;
}
CouponTypeEnum.class:错误码枚举类
@Getter
publicenumCouponTypeEnum{
PARAMETER_ERROR(1001,"请求参数有误!"),
UNKNOWN_ERROR(9999,"未知的错误!”);
/**
*状态值
*/
privateintcouponType;
/**
*状态描述
*/
privateStringcouponTypeDesc;
CouponTypeEnum(intcouponType,StringcouponTypeDesc){
this.couponType=couponType;
this.couponTypeDesc=couponTypeDesc;
}
publicstaticStringgetDescByType(intcouponType){
for(CouponTypeEnumtype:CouponTypeEnum.values()){
if(type.couponType==couponType){
returntype.couponTypeDesc;
}
}
returnnull;
}
publicStringgetcouponTypeStr(){
returnString.valueOf(this.couponType);
}
}
BusinessException.java:自定义业务异常类
/**
*业务自定义异常
*/
@Getter
publicclassBusinessExceptionextendsRuntimeException{
privatestaticfinallongserialVersionUID=-1895174013651345407L;
privatefinalCouponTypeEnumerrorCode;
privateStringprimaryErrorCode;
privateStringprimaryErrorMsg;
privateStringprimaryErrorIP;
publicBusinessException(CouponTypeEnumerrorCode){
this(errorCode,errorCode.getCouponTypeDesc());
}
publicBusinessException(CouponTypeEnumerrorCode,Stringmessage){
super(message);
this.errorCode=errorCode;
}
publicBusinessException(CouponTypeEnumerrorCode,Stringmessage,StringprimaryErrorCode,StringprimaryErrorMsg,StringprimaryErrorIP){
super(message);
this.errorCode=errorCode;
this.primaryErrorCode=primaryErrorCode;
this.primaryErrorMsg=primaryErrorMsg;
this.primaryErrorIP=primaryErrorIP;
}
publicBusinessException(CouponTypeEnumerrorCode,StringprimaryErrorCode,StringprimaryErrorMsg,StringprimaryErrorIP){
this(errorCode,errorCode.getCouponTypeDesc());
this.primaryErrorCode=primaryErrorCode;
this.primaryErrorMsg=primaryErrorMsg;
this.primaryErrorIP=primaryErrorIP;
}
}
GlobalExceptionHandler.class拦截异常并统一处理
- MissingServletRequestParameterException:必填项为null异常
- HttpMessageNotReadableException:参数类型不匹配异常
- MethodArgumentNotValidException:JSON校验失败异常(比如长度等)
- BusinessException:自定义的异常
- Exception:其他异常
@RestControllerAdvice("com.luo.producer.controller")
@Slf4j
publicclassGlobalExceptionHandler{
/**
*忽略参数异常处理器
*
*@parame忽略参数异常
*@returnResponse
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MissingServletRequestParameterException.class)
publicResponseparameterMissingExceptionHandler(MissingServletRequestParameterExceptione){
log.error("",e);
returnnewResponse(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(),"请求参数"+e.getParameterName()+"不能为空");
}
/**
*缺少请求体异常处理器
*
*@parame缺少请求体异常
*@returnResponse
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(HttpMessageNotReadableException.class)
publicResponseparameterBodyMissingExceptionHandler(HttpMessageNotReadableExceptione){
log.error("",e);
returnnewResponse(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(),"参数体不能为空");
}
/**
*参数效验异常处理器
*
*@parame参数验证异常
*@returnResponseInfo
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
publicResponseparameterExceptionHandler(MethodArgumentNotValidExceptione){
log.error("",e);
//获取异常信息
BindingResultexceptions=e.getBindingResult();
//判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
if(exceptions.hasErrors()){
Listerrors=exceptions.getAllErrors();
if(!errors.isEmpty()){
//这里列出了全部错误参数,按正常逻辑,只需要第一条错误即可
FieldErrorfieldError=(FieldError)errors.get(0);
returnnewResponse(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(),fieldError.getDefaultMessage());
}
}
returnnewResponse(CouponTypeEnum.PARAMETER_ERROR);
}
/**
*自定义参数错误异常处理器
*
*@parame自定义参数
*@returnResponseInfo
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler({BusinessException.class})
publicResponseparamExceptionHandler(BusinessExceptione){
log.error("",e);
//判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
if(!StringUtils.isEmpty(e.getMessage())){
returnnewResponse(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(),e.getMessage());
}
returnnewResponse(CouponTypeEnum.PARAMETER_ERROR);
}
/**
*其他异常
*
*@parame
*@return
*/
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler({Exception.class})
publicResponseotherExceptionHandler(Exceptione){
log.error("其他异常",e);
//判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
if(!StringUtils.isEmpty(e.getMessage())){
returnnewResponse(CouponTypeEnum.UNKNOWN_ERROR.getcouponTypeStr(),e.getMessage());
}
returnnewResponse(CouponTypeEnum.UNKNOWN_ERROR);
}
}
验证
测试接口
@Valid被标记的实体将会开启一个校验的功能
@RequestBody:请求实体需要加上@RequestBody否则MethodArgumentNotValidException异常将会被识别成Exception异常,提示信息将与预期不符。
@RestController
@Slf4j
publicclassUserController{
@PostMapping("/helloluo")
@MyPermissionTag(value="true")
publicStringhelloluo(@RequestBody@ValidUserPojoRequserPojoReq){
return"HelloWorld”+userPojoReq;
}
}
模拟请求参数,进行接口访问:
到此这篇关于SpringBoot使用validation-api实现参数校验的示例的文章就介绍到这了,更多相关SpringBootvalidation参数校验内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。