007-Spring MVC 参数验证3-自定义验证

自定义验证

Hibernate Validate提供了很丰富的内置验证注解。当这些还不能满足你的要求,我们可以自定义验证注解。
比如:我们自定义一个关键字过滤的验证规则注解如下。

1. 编写验证规则注解类

package com.yyoo.springmvc.valid;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {KeyWordValidator.class})
@Documented
@Repeatable(KeyWord.List.class)
public @interface KeyWord {

    String message() default "{com.yyoo.springmvc.valid.KeyWord.message}";

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

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

    String keyWords() default "";

    @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @interface List {
        KeyWord[] value();
    }

}

几个元注解的解释

  • @Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE, ElementType.TYPE_USE }):定义约束支持的目标元素类型。@KeyWord可用于字段(元素类型FIELD)、JavaBeans 属性以及方法返回值(METHOD)、方法/构造函数参数(PARAMETER)和参数化类型的类型参数(TYPE_USE)。元素类型ANNOTATION_TYPE允许创建构成约束的基础上@KeyWord。
  • @Retention(RetentionPolicy.RUNTIME): 该类型的注解将在运行时通过反射的方式可用(我们定义一般都使用该方式)
    @Constraint(validatedBy = {KeyWordValidator.class}): 将注解类型标记为约束注解,并指定对应的验证器类为KeyWordValidator(验证器我们在下文定义)。如果约束可以用于多种数据类型,则可以指定多个验证器,每个数据类型一个。
  • @Documented: 注解是否将包含在JavaDoc中
  • @Repeatable(List.class):表示注解可以在同一个地方重复多次,通常配置不同。List就是我们注解类中的定义的内部注解List。

验证注解有如下几个必要的属性

  • message:错误消息属性。我们设置了默认值{com.yyoo.springmvc.valid.KeyWord.message},表示它将读取国际化文件的消息配置
  • groups:指定验证组。这必须默认为 Class<?> 类型的空数组。
  • payload:Jakarta Bean Validation API 的客户端可以使用该属性将自定义负载对象分配给约束。API 本身不使用此属性。

自定义属性

示例中keyWords属性是我们的自定义属性,可根据自身的需求进行定义。

内部注释List

它允许@CheckCase在同一元素上指定多个 注释,例如使用不同的验证组和消息。虽然可以使用另一个名称,但 Jakarta Bean 验证规范建议使用 List 并使注释成为相应约束类型的内部注释。

2. 定义验证器类KeyWordValidator

package com.yyoo.springmvc.valid;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class KeyWordValidator implements ConstraintValidator<KeyWord,String> {

    private String keyWords;

    @Override
    public void initialize(KeyWord constraintAnnotation) {
        // 将注解上初始化的值导入
        this.keyWords = constraintAnnotation.keyWords();
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        // 一个简单的规则,如果包含关键字则不通过
        if(this.keyWords.contains(s)){
            return false;
        }

        return true;
    }
}

javax.validation.ConstraintValidator<A extends Annotation, T>接口

每个自定义验证器,都需要实现该接口

initialize方法提供验证器的初始化,如我们的示例,就是将我们在使用注解的时候赋值的keyWords属性,将其值导入到我们的当前验证器。然后在isValid方法中使用。

ConstraintValidatorContext

我们的示例没有使用该参数。但比如我们需要在验证器中定义一些其他的提示信息,我们可以如下使用:

if ( !isValid ) {
            constraintContext.disableDefaultConstraintViolation();
            constraintContext.buildConstraintViolationWithTemplate(
                    "{com.yyoo.springmvc.valid.KeyWord.other.message}"
            )
            .addConstraintViolation();
        }

验证示例

   	@NotNull
    @KeyWord(keyWords = "name,age",message = "姓名不能包含{keyWords}",groups = GroupThree.class)
    private String name;

当name属性包含name、age属性时将会提示姓名不能包含name、age

更多的高级用法和功能(如自定义验证注解、自定义交叉验证等)请参考Hibernate Validator

上一篇:006-Spring MVC参数验证2-分组验证
下一篇:008-Spring MVC ViewResolver视图解析器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值