详解创建自定义验证 spring

问题:

     问题描述:从页面上获取用户输入的项目值,登录到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();
	}

	@Override
	public 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,大功告成!


















  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值