自定义枚举Validated校验注解

2023-10-18 16:32:19 浏览数 (1)

自定义枚举Validated校验注解

一、介绍

在以前的文章中,有解释使用过@Valid注解的使用

Valid注解使用及扩展 | 半月无霜 (banmoon.top)

Validated分组校验及扩展 | 半月无霜 (banmoon.top)

本篇分享一个自定义校验注解,可以配合枚举使用,对入参的有效值进行校验。

比如说一些状态值,入参必须要符合定义的状态值

二、代码

注解

代码语言:javascript复制
package com.banmoon.validator;

import com.banmoon.business.enums.MyEnum;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Constraint(validatedBy = {EnumValidValidator.class})
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnumValid {

    String message() default "不符合的枚举类型";

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

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

    Class<? extends MyEnum<?>> enumClass();

    /**
     * 分隔符,作用于{@link java.lang.String}上
     */
    String separator() default ",";
}

校验器

代码语言:javascript复制
package com.banmoon.validator;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.banmoon.business.enums.MyEnum;
import com.banmoon.utils.StreamUtil;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@SuppressWarnings("all")
public class EnumValidValidator implements ConstraintValidator<EnumValid, Object> {

    private List<?> list;

    private String separator;

    @Override
    public void initialize(EnumValid constraintAnnotation) {
        Class<? extends MyEnum<?>> enumClass = constraintAnnotation.enumClass();
        MyEnum<?>[] enums = enumClass.getEnumConstants();
        list = Arrays.stream(enums).map(MyEnum::getCode).collect(Collectors.toList());
        separator = constraintAnnotation.separator();
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        if (Objects.isNull(o)) {
            return true;
        }
        if (o instanceof Collection) {
            Collection<?> paramList = (Collection<?>) o;
            return list.containsAll(paramList);
        } else if (o instanceof String) {
            List<String> paramList = StrUtil.split(((String) o), separator);
            List<?> resultList = StreamUtil.difference(paramList, list, Objects::equals, Function.identity());
            return CollUtil.isEmpty(resultList);
        } else {
            return list.contains(o);
        }
    }
}

三、使用

代码语言:javascript复制
package com.banmoon.controller;

import com.banmoon.business.dto.ResultData;
import com.banmoon.request.valid.MyEnumValidRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * Valid 校验
 *
 * @author banmoon
 */
@Validated
@RestController
@RequestMapping("/valid")
public class ValidController {

    @PostMapping("/myEnumValid")
    public ResultData<Void> myEnumValid(@Valid @RequestBody MyEnumValidRequest request) {
        return ResultData.success();
    }
}
代码语言:javascript复制
package com.banmoon.request.valid;

import com.banmoon.business.enums.MyEnum;
import com.banmoon.validator.EnumValid;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Set;

@Data
@ApiModel("验证自定义校验注解-入参")
@NoArgsConstructor
public class MyEnumValidRequest {


    @EnumValid(enumClass = ValidEnum.class)
    @ApiModelProperty("校验字符串")
    private String strParam;

    @EnumValid(enumClass = ValidEnum.class, separator = ",")
    @ApiModelProperty("校验字符串List")
    private String strListParam;

    @EnumValid(enumClass = ValidEnum.class)
    @ApiModelProperty("校验List")
    private List<String> listParam;

    @EnumValid(enumClass = ValidEnum.class)
    @ApiModelProperty("校验Set")
    private Set<String> setParam;

    @Getter
    @AllArgsConstructor
    public enum ValidEnum implements MyEnum<String> {

        NORMAL("1", "未开始"),
        WAIT("2", "等待运行"),
        RUNNING("3", "正在运行"),
        FINISH("4", "运行完成"),
        ;

        private final String code;
        private final String msg;
    }

}

请求接口

四、最后

我是半月,你我一同共勉!!!

0 人点赞