SpringBoot使用validation-api实现对枚举类参数校验的方法

 更新时间:2020年12月09日 14:42:55   作者:溪源的奇思妙想  
这篇文章主要介绍了SpringBoot使用validation-api实现对枚举类参数校验,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

前言

之前写了一个博客是关于使用SpringBoot使用validation-api实现参数校验,当时使用的注解都是validation-api自带的注解只能完成对空值、长度等简单的校验,在我们日常的使用当中会遇到对参数是否在枚举值类的校验,针对这种情况我们怎么来实现呢?

SpringBoot使用validation-api实现参数校验可参考我的博客:SpringBoot使用validation-api实现参数校验

正文

SpringBoot使用validation-api实现对枚举类参数校验

ValidationApi框架就是用来解决参数校验中代码冗余问题,ValidationApi框架提供一些注解用来帮助我们对请求参数进行校验。

Maven依赖

<!--参数校验-->
<dependency>
 <groupId>javax.validation</groupId>
 <artifactId>validation-api</artifactId>
 <version>2.0.1.Final</version>
</dependency>


<!--提供一些字符串操作-->
<dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-lang3</artifactId>
 <version>3.3.2</version>
</dependency>


<!--lombok-->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.2</version>
 <optional>true</optional>
</dependency>


<!--knife4j接口-->
<dependency>
 <groupId>com.github.xiaoymin</groupId>
 <artifactId>knife4j-spring-boot-starter</artifactId>
 <version>2.0.4</version>
</dependency>

EnumValidate:用于对枚举校验的接口

/**
* 用于实现枚举类的校验
*/
public interface EnumValidate<T> {

 /**
 * 校验枚举值是否存在
 */
 boolean existValidate(T value);
}

ActionTypeEnumValid:用于对枚举类校验的自定义注解

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ActionTypeEnumValidator.class})
@Documented
public @interface ActionTypeEnumValid {

 String message() default "";


 Class<?>[] groups() default {};


 Class<? extends Payload>[] payload() default {};


 Class<?>[] target() default {};

 /**
 * 允许的枚举
 *
 * @return
 */
 Class<? extends Enum<?>> enumClass();
}

ActionTypeEnumValidator:枚举校验器

/**
* 用于校验ActionTypeEnumValidator
*/
public class ActionTypeEnumValidator implements ConstraintValidator<ActionTypeEnumValid,String> {


 private Class<? extends Enum> enumClass;


 @Override
 public void initialize(ActionTypeEnumValid actionTypeEnumValid) {
 enumClass = actionTypeEnumValid.enumClass();
 }


 @Override
 public boolean isValid(String value, ConstraintValidatorContext context) {
 if (value == null || "".equals(value)) {
 return true;
 }


 EnumValidate[] enums = (EnumValidate[]) enumClass.getEnumConstants();
 if(enums ==null || enums.length == 0){
 return false;
 }


 return enums[0].existValidate(value);
 }

}

ActionTypeEnum:枚举类

@Getter
public enum ActionTypeEnum implements EnumValidate<String> {


 ACTION_INVOKR("invoke", "invoke"),
 UNKNOWN_ERROR("no", "no");

 /**
 * 状态值
 */
 private String couponType;

 /**
 * 状态描述
 */
 private String couponTypeDesc;

 ActionTypeEnum(String couponType, String couponTypeDesc) {
 this.couponType = couponType;
 this.couponTypeDesc = couponTypeDesc;
 }


 public static String getDescByType(String couponType) {
 for (ActionTypeEnum type : ActionTypeEnum.values()) {
 if (type.couponType.equals(couponType) ) {
 return type.couponTypeDesc;
 }
 }
 return null;
 }

 /**
 * 判断是否在枚举类当中
 * @param value
 * @return
 */
 @Override
 public boolean existValidate(String value) {
 if (value == null || "".equals(value)) {
 return false;
 }
 for (ActionTypeEnum testEnum : ActionTypeEnum.values()) {
 if (testEnum.getCouponType().equalsIgnoreCase(value)) {
 return true;
 }
 }
 return false;
 }

 public String getcouponTypeStr() {
 return String.valueOf(this.couponType);
 }
}

GlobalExceptionHandler:使用SpringMVC提供的异常处理机制,对ValidationApi的异常进行封装

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

 /**
 * 忽略参数异常处理器
 *
 * @param e 忽略参数异常
 * @return Response
 */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler(MissingServletRequestParameterException.class)
 public ResponseResult parameterMissingExceptionHandler(MissingServletRequestParameterException e) {
 log.error("参数异常", e);
 return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), "请求参数 " + e.getParameterName() + " 不能为空");
 }


 /**
 * 缺少请求体异常处理器
 *
 * @param e 缺少请求体异常
 * @return Response
 */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler(HttpMessageNotReadableException.class)
 public ResponseResult parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {
 log.error("缺少请求体异常", e);
 return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), "参数体不能为空");
 }


 /**
 * 参数效验异常处理器
 *
 * @param e 参数验证异常
 * @return ResponseInfo
 */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler(MethodArgumentNotValidException.class)
 public ResponseResult parameterExceptionHandler(MethodArgumentNotValidException e) {
 log.error("参数验证异常", e);
 // 获取异常信息
 BindingResult exceptions = e.getBindingResult();
 // 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
 if (exceptions.hasErrors()) {
 List<ObjectError> errors = exceptions.getAllErrors();
 if (!errors.isEmpty()) {
 // 这里列出了全部错误参数,按正常逻辑,只需要第一条错误即可
 FieldError fieldError = (FieldError) errors.get(0);
 return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), fieldError.getDefaultMessage());
 }
 }
 return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR);
 }


 /**
 * 自定义参数错误异常处理器
 *
 * @param e 自定义参数
 * @return ResponseInfo
 */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler({BusinessException.class})
 public ResponseResult paramExceptionHandler(BusinessException e) {
 log.error("业务异常", e);
 // 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
 if (!StringUtils.isEmpty(e.getMessage())) {
 return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), e.getMessage());
 }
 return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR);
 }


 /**
 * 其他异常
 *
 * @param e
 * @return
 */
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 @ExceptionHandler({Exception.class})
 public ResponseResult otherExceptionHandler(Exception e) {
 log.error("其他异常", e);
 // 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息
 if (!StringUtils.isEmpty(e.getMessage())) {
 return new ResponseResult(CouponTypeEnum.UNKNOWN_ERROR.getcouponTypeStr(), e.getMessage());
 }
 return new ResponseResult(CouponTypeEnum.UNKNOWN_ERROR);
 }
}

验证

请求的封装类

/**
* 指令的封装类
*/
@Getter
@Setter
@ToString
public class CommandPOJO implements Serializable {
 private static final long serialVersionUID = -8497328408069586664L;

 //指令
 @NotNull(message = "指令为必填项,不得为空")
 @ActionTypeEnumValid(message = "该指令暂不支持,暂时只支持invoke", enumClass = ActionTypeEnum.class)
 private String action ="invoke";

}

请求接口

@Valid 用于开启请求参数校验

@RestController
@Slf4j
@Api(value = "远程调用模块")
@RequestMapping("/xiyuanrpc")
public class RPCController {

 @PostMapping("/rpcNettybyInvoke")
 @ApiOperation(value = "rpc远程调用")
 @InvokeParameterCheck
 @MethodLogPrint
 public ResponseResult rpcNettybyInvoke(@Valid @RequestBody CommandPOJO pojo) {
 return NettyClientUtil.rpcNetty(pojo);
 }

}

通过Knife4j访问对应接口

在这里插入图片描述

源码

项目源码可从的我的github中获取:github源码地址

到此这篇关于SpringBoot使用validation-api实现对枚举类参数校验的方法的文章就介绍到这了,更多相关SpringBoot枚举类参数校验内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java Swing组件实现进度监视功能示例

    Java Swing组件实现进度监视功能示例

    这篇文章主要介绍了Java Swing组件实现进度监视功能,结合完整实例形式详细分析了Java基于Swing组件实现进度条显示功能的具体操作技巧与相关注意事项,需要的朋友可以参考下
    2018-02-02
  • Java代码规范与质量检测插件SonarLint的使用

    Java代码规范与质量检测插件SonarLint的使用

    本文主要介绍了Java代码规范与质量检测插件SonarLint的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Java面向对象的封装你了解吗

    Java面向对象的封装你了解吗

    这篇文章主要为大家详细介绍了Java面向对象的封装,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • springboot2升级到springboot3过程相关修改记录

    springboot2升级到springboot3过程相关修改记录

    本文详细记录了将Spring Boot 2升级到Spring Boot 3的过程,包括升级JDK到17、修改依赖、配置文件调整以及处理一些特定问题,如Redisson版本升级和Swagger配置,感兴趣的朋友跟随小编一起看看吧
    2024-12-12
  • 浅析Mysql中的视图

    浅析Mysql中的视图

    这篇文章主要介绍了浅析Mysql中的视图,视图是从一个或者多个表中导出的表,视图的行为与表非常相似,在视图中用户可以使用SELECT语句查询数据,以及使用INSERT、UPDATE和DELETE修改记录,需要的朋友可以参考下
    2023-05-05
  • springboot整合druid连接池的步骤

    springboot整合druid连接池的步骤

    这篇文章主要介绍了springboot整合druid连接池的步骤,帮助大家更好的理解和学习springboot框架,感兴趣的朋友可以了解下
    2020-11-11
  • JDK(免安装)各种版本下载及配置详细图文教程

    JDK(免安装)各种版本下载及配置详细图文教程

    这篇文章主要给大家介绍了关于JDK(免安装)各种版本下载及配置的相关资料,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-07-07
  • JAVA使用随机数实现概率抽奖

    JAVA使用随机数实现概率抽奖

    这篇文章主要为大家详细介绍了JAVA使用随机数实现概率抽奖,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • JAVA基础面试题整理

    JAVA基础面试题整理

    在本篇文章里小编给大家整理的是关于JAVA基础面试题的整理内容,需要的朋友们可以参考下。
    2019-10-10
  • SpringBoot依赖注入的三种方式

    SpringBoot依赖注入的三种方式

    本文将通过代码示例详细介绍SpringBoot依赖注入的三种方式,对学习依赖注入有一定的参考价值,需要的朋友可以参考一下
    2023-04-04

最新评论