目录
资料参考地址1:
spring中@Validated注解的使用
一 @Validated分组校验(单层对象)
@Valid不提供分组的功能
由于在项目中存在几个接口共用一个实体类,在不同的接口中某些字段的规则是不一样的,如果想要用同一个对象的话,这个时候就需要用到分组的功能了,指定字段在某个组别下的规则。
不指定分组,只校验默认的组别Default,导包import javax.validation.groups.Default;
1.1 分组校验测试参数
@Data
@Accessors(chain = true)
public class GroupParam {
@NotBlank(message = "更新组不能为空", groups = {UpdateGroup.class})
private String updateValue;
@NotBlank(message = "默认组不能为空")
private String defaultValue;
@NotBlank(message = "添加组不能为空", groups = {AddGroup.class})
private String addValue;
@NotBlank(message = "自定义分组组不能为空", groups = {CustomGroup.class})
private String customValue;
private Boolean status;
}
1.2 分组接口
public interface AddGroup {
}
public interface UpdateGroup {
}
public interface CustomGroup {
}
1.3 controller测试接口
/**
* 不指定分组,只校验默认的组别Default
* @param param
* @return
*/
@PostMapping("/default")
public String defaultGroup(@Validated @RequestBody GroupParam param) {
return "Validated注解默认成功!";
}
/**
* 测试分组校验(新建)
* 指定组别校验,校验自定义的AddGroup组别
* @param param 参数
* @return
*/
@PostMapping("/add")
public String groupAdd(@Validated({AddGroup.class}) @RequestBody GroupParam param) {
log.info(param.toString());
return "Validated注解默认成功!";
}
/**
* 测试分组校验(更新)
* 指定组别校验,校验自定义的UpdateGroup组别和默认的组别Default
* @param param 参数
* @return
*/
@PostMapping("/update")
public String groupUpdate(@Validated({UpdateGroup.class,Default.class}) @RequestBody GroupParam param) {
log.info(param.toString());
return "Validated注解默认成功!";
}
二 @Validated根据前端的传参状态进行校验(单层对象)
@Validated根据前端的传参状态,添加不同的组别,最后进行手动校验(单层对象)
2.1 controller测试接口
/**
* 框架先校验AddGroup组别的参数,然后如果状态是类别2,则需要手动添加要
校验CustomGroup和Default组别,最后再调用校验的工具类
*
* @param param
* @return
*/
@PostMapping("/manual")
public String manualGroup(@Validated({AddGroup.class}) @RequestBody GroupParam param) throws Exception {
List<Class> groupClasses = new ArrayList<>();
if (Boolean.TRUE.equals(param.getStatus())) {
groupClasses.add(CustomGroup.class);
groupClasses.add(Default.class);
}
//转成数组
Class[] groups = groupClasses.toArray(new Class[0]);
//手动调用校验的方法
ValidatorUtils.validateEntity(param, groups);
return "Validated注解手动添加成功!";
}
2.2 手动校验工具类
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;
@Slf4j
public class ValidatorUtils {
private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
/**
* 手动校验
*
* @param object
* @param groups
* @throws Exception
*/
public static void validateEntity(Object object, Class<?>... groups) throws Exception {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty()) {
StringBuilder errorMsg = new StringBuilder();
for (ConstraintViolation<?> e : constraintViolations) {
errorMsg.append(e.getMessage() + ";");
}
throw new Exception(errorMsg.substring(0, errorMsg.toString().length() - 1));
}
}
}
三 @Validated自定义注解校验
如果框架提供的注解不满足实际开发中业务的校验,可以自定义一个校验注解来实现
3.1自定义一个注解
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 自定义注解
* @author lyn
*/
@Target({ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RUNTIME)
@Documented
//此处指定了该注解的实现类为ListNotHasNullValidatorImpl
@Constraint(validatedBy = ListNotHasNullValidatorImpl.class)
//在同一个地方使用相同的注解会报错,所以该注解是装同一个注解的容器,
@Repeatable(ListNotHasNull.List.class)
public @interface ListNotHasNull {
/**
* 添加value属性,可以作为校验时的条件,若不需要,可去掉此处定义
*/
int value() default 0;
/**
* 默认的报错提示信息
*
* @return
*/
String message() default "List集合中的元素不能含有null元素";
Class<?>[] groups() default {};
/**
* 约束注解的有效负载 将一些元数据信息与该约束注解相关联
*
* @return
*/
Class<? extends Payload>[] payload() default {};
/**
* 定义List,为了让Bean的一个属性上可以添加多套规则
*/
@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Documented
@interface List {
ListNotHasNull[] value();
}
}
3.2 实现ConstraintValidator接口
使用泛型会报错,只能使用固定对象
待解决
import lombok.SneakyThrows;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
/**
* 自定义注解的具体校验规则实现
* 集合不能为空,并且对象里面的属性值也不能为空
*
* @author lyn
*/
@Component
public class ListNotHasNullValidatorImpl implements ConstraintValidator<ListNotHasNull, List<User>> {
private int value;
@Override
public void initialize(ListNotHasNull constraintAnnotation) {
//传入value 值,可以在校验中使用
this.value = constraintAnnotation.value();
}
/**
* 返回false就会抛出错误的信息
* @param list
* @param constraintValidatorContext
* @return
*/
@SneakyThrows
@Override
public boolean isValid(List<User> list, ConstraintValidatorContext constraintValidatorContext) {
if (list == null || list.size() == 0) {
return false;
}
for (User obj : list) {
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
Class<?> type = field.getType();
// 设置些属性是可以访问的
boolean isStatic = Modifier.isStatic(field.getModifiers());
if (isStatic) {
continue;
}
// 设置些属性是可以访问的
field.setAccessible(true);
// 得到此属性的值
Object val = field.get(obj);
if (val == null) {
return false;
}
}
}
return true;
}
}
3.3 controller接口
/**
* 自定义注解测试
* @param company 参数
* @return
*/
@PostMapping("/defined")
public String definedAdd(@Validated(value = {AddGroup.class}) @RequestBody Company company) {
return "自定义注解添加成功!";
}
3.4 实体类
@Data
public class Company {
@ListNotHasNull(message = "集合不能为空,并且对象里面的属性值也不能为空", groups = {AddGroup.class})
private List<User> users;
}
@Data
public class User {
private String name;
private Integer age;
private String address;
}
四、@Validated和@Valid的不同
- @Valid用来标记验证属性和方法返回值,支持进行级联和递归校验(可以结合@Validated注解在嵌套对象中使用)。
- @Validated是Spring提供的注解,提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制。
- 在Controller中校验方法参数时,使用@Valid和@Validated并无特殊差异(若不需要分组校验的话)。
- @Validated只能用在类、方法和参数上,而@Valid可用于类、方法、字段、构造器和参数上。
- 他们的所属的包不同,@Validated属于spring,而@Valid属于javax。
- @Validated :
org.springframework.validation.annotation.Validated
- @Valid:
javax.validation.Valid
总结:
建议直接用@Validated,功能比@Valid注解强大
标签:hibernate,校验,param,validator,import,注解,Validated,class From: https://www.cnblogs.com/lyn8100/p/16837200.html