自定义枚举Validated校验注解

一、介绍

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

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

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

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

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

二、代码

注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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 ",";
}

校验器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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);
}
}
}

三、使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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;
}

}

请求接口

image-20230830142142525

四、最后

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