详解创建自定义验证 spring

来源:互联网 发布:x-japan 知乎 编辑:程序博客网 时间:2024/06/10 14:05

问题:

     问题描述:从页面上获取用户输入的项目值,登录到DB中的某个Table表里,出现登录异常。

     问题原因:Table里的属性有最大长度check,输入的项目长度大于表中属性最大长度。

                      但实际上在登录操作之前,已经对属性最大长度进行了check。

                      Form里对属性做了如下操作:例如DB可登录最大长度20

                      @Size(min = 1, max = 20)
                      public String name;

     根本原因:DB中属性的最大长度单位是字节,但@Size做的check是字符串的长度check,单位是字符。

                      通俗的理解就是,两边的check单位不一致。

                     例如 String   a = "汉字"; 此时 字符串a的字符长度为2,但一个汉字等于2个字节,也就是说

                     字符串a的字节长度是4。


解决方法:

          spring框架自带的@size已经不能满足我们此时的需求,打算自己实装一个check类来替代@size的作用。


实现步骤:

         要完成一个自定义的注解,需要下面三个步骤。

           第一步:首先定义一个validation check 注解

           第二步:写个类来实现第一步定义的注解,即实现验证器

           第三步:添加一个默认的错误信息


下面我们就开始吧。

     引入validation包。因为我的是maven工程。pom.xml里添加下面配置

     <dependency>
            <groupid>javax.validation</groupid>
            <artifactid>validation-api</artifactid>
            <version>1.1.0.Final</version>
     </dependency>

    如果是普通java工程,直接导入validation-api-1.1.0.Final.jar即可。

    这个包提供的常用注解及说明。

   

     下面写一个注解类,CharSize.java

    

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;import static java.lang.annotation.ElementType.CONSTRUCTOR;import static java.lang.annotation.ElementType.FIELD;import static java.lang.annotation.ElementType.METHOD;import static java.lang.annotation.ElementType.PARAMETER;import java.lang.annotation.Documented;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import javax.validation.Constraint;import javax.validation.Payload;@Documented@Constraint(validatedBy = CharSizeValidator.class)@Target({ METHOD, FIELD, ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface CharSize {String message() default "{javax.validation.constraints.Size.message}";Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };/** * @return size the element must be higher or equal to */int min() default 0;/** * @return size the element must be lower or equal to */int max() default Integer.MAX_VALUE;}


    详细说明:

                  @Target表示该注解可以用在什么地方,比如可以出现在field属性定义上,method上,或者是另一个annotation注解上。

                      这里限定只能出现在方法,属性和另一个注解上。

                  @Constraint表示该注解的实现类,表示哪个验证器提供验证,这里是CharSizeValidator.class这个类来实现check功能。

                  @Retention表示该注解的保存范围。RUNTIME表示在源码,编译好的class文件中保存信息,执行的时候加载到JVM中去。

                  @interface表明这是一个注解,关键字。message(),groups(),payload()这个三个方法一般约束接口都具备,其中message()是必须的。

                  default表示默认初期值,"{javax.validation.constraints.Size.message}";这里我没有自己定义新的默认message,而且沿用@size的

                             默认message,(改善要,理应新建一个message管理的属性资源文件),这里{}表示引用资源文件,{}内是文件信息的可以,如果

                            不加{},表示引号内的内容就是消息本身。

                  groups()表示该约束属于哪个验证组,分组check。

                  min和max是我自己添加进去的属性。


   下面就来实现这个约束,CharSizeValidator.java

import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;public class CharSizeValidator implements ConstraintValidator<CharSize,String> {public int maxCharSize;public void initialize(CharSize charSize) {this.maxCharSize = charSize.max();}@Overridepublic boolean isValid(String StringValue, ConstraintValidatorContext context) {if(StringValue == null){return true;}int f = StringValue.getBytes().length;if(f > maxCharSize){return false;}else{return true;}}}

    Form里添加我们自定义的注解吧。EchoForm.java(其他代码这里就省略了)

     @NotNull // (1)
     @CharSize(max = 20, message = "name 不能长于20位字节!"
     public String name;

      这里对name属性 进行charSize 检证,长度设置20字节,提供出错时抛出的提示信息。


     测试:在controller.java里如下方法

    

    @RequestMapping(value = "hello", method = {RequestMethod.GET, RequestMethod.POST})    public String hello(@Validated EchoForm form, BindingResult result, Model model) {     if (result.hasErrors()) {     return "home2";    }    return "home2";    }

    这里注意@Validated check对象的后面需要紧跟 BindingResult 对象


    


       测试时输入了16个汉字,共32个字节,大于20个字节,成功捕获,满足我们的需求。

       OK,大功告成!


















0 0
原创粉丝点击