一.引入pom
<!-- validation -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
二.定义实体
注意:存在实体嵌套的时候要在对象类型属性加@Valid注解,否则嵌套实体定义的校验注解不生效
1.定义DTO
package com.example.redission.entity;
import com.example.redission.annotation.LegalEnum;
import com.example.redission.enums.ScopeEnum;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @version 1.0
* @date 2024/5/13
* @description
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class WelcomeDto {
private String id;
@NotBlank(message = "标题不能为空")
private String name;
@NotBlank(message = "范围不能为空")
@LegalEnum(value = ScopeEnum.class, message = "范围枚举值不合法")
private String scope;
@Valid
@Size(max = 5, message = "User不能超过5个")
private List<User> userList;
}
2.User
package com.example.redission.entity;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author 土
* @version 1.0
* @date 2024/5/15
* @description
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
@NotBlank(message = "标题不能为空")
private String name;
@Valid
@Size(max = 5, message = "Address不能超过5个")
@NotNull
private List<Address> addressList;
}
3.Address
package com.example.redission.entity;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author OP0345
* @version 1.0
* @date 2024/5/15
* @description
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Address {
@NotBlank(message = "省份不能为空")
private String province;
}
三.定义枚举类
package com.example.redission.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.stream.Stream;
@Getter
@AllArgsConstructor
public enum ScopeEnum {
ALL_USER("all", "全部企微号"),
TAG("tag", "指定层级"),
SOME_USER("some", "指定企微号");
private final String type;
private final String desc;
public static ScopeEnum findBy(String value) {
return Stream.of(ScopeEnum.values())
.filter(item -> item.getType().equals(value))
.findFirst()
.orElse(null);
}
}
四.自定义枚举参数校验注解
package com.example.redission.annotation;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
/**
* 枚举类型校验
*
* @author :
*/
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = LegalEnum.EnumValidator.class)
public @interface LegalEnum {
String message() default "无效的枚举值";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<? extends Enum<?>> value();
class EnumValidator implements ConstraintValidator<LegalEnum, Object> {
private Class enumClass;
@Override
public void initialize(LegalEnum constraintAnnotation) {
this.enumClass = constraintAnnotation.value();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
if (value == null) {
return false;
}
if (!enumClass.isEnum()) {
throw new IllegalArgumentException(enumClass.getSimpleName() + " is not an enum type");
}
try {
//基于type属性
Field field = enumClass.getDeclaredField("type");
field.setAccessible(true);
Object[] enumConstants = enumClass.getEnumConstants();
for (Object enumConstant : enumConstants) {
Object fieldValue = field.get(enumConstant);
if (fieldValue != null && fieldValue.equals(value)) {
return true;
}
}
return false;
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException("Error validating enum", e);
}
}
}
}
五.controller接口验证
package com.example.redission.controller;
import com.example.redission.annotation.RateLimit;
import com.example.redission.entity.WelcomeDto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @author 土
* @version 1.0
* @description controller
*/
@RestController
@RequestMapping("/hello")
@Slf4j
@RequiredArgsConstructor
@Validated
public class ApiController {
// @RedisLock(key = "'lock_' + #str")
@GetMapping(value = "say", produces = MediaType.APPLICATION_JSON_VALUE)
public String send(@RequestParam(name = "str") @NotNull @NotBlank(message = "str必输") String str) {
return str;
}
@PostMapping(value = "addOne", produces = MediaType.APPLICATION_JSON_VALUE)
public String addOne(@Validated @RequestBody WelcomeDto dto) {
System.out.println("进来了");
return dto.getName();
}
}