在基于SpringMVC框架的开发中,我们经常要对用户提交的字段进行合法性验证,比如整数类型的字段有个范围约束,我们会用@Range(min=1, max=4)。在实际应用开发中,我们经常碰到一些自己业务的场景要自定义一些验证规则,而这是标准的JSR-303Hibernate Validation所不具备的,所以我们就要根据JSR-303的规范来扩展我们自定义的验证规则注释.

假设我们现在有个接口要接收一个手机的字段, 它的约束规则是13位数字字符. 我们可以通过正则表达式完成: ^\d{13}$来验证. 下面是个javabean代码:

public class Person{
@Phone
private String phone;
}

我们再来看下@Phone的代码.

@Documented
@Constraint(validatedBy = PhoneConstraintValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Phone {
String message() default "{Phone}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

这个注解类看起来复杂, 其实不然. 因为这基本上每个扩展验证注解都必需定义的三个方法, 是规范定义的, 所以我们可以像个模板一样copy过来改下. 这里要注意的是这个message方法, 定义了如果验证出错时要显示的消息内容. 对于消息格式和规范, 可以使用标准的Spring Message Resource Bindle来, 可以参考这篇. 现在定义了注解, 正如你所料, 我们要定义下具体的业务规则:

public class PhoneConstraintValidator implements ConstraintValidator<Phone, String> {

	@Override
public void initialize(Phone phone) { } @Override
public boolean isValid(String phoneField, ConstraintValidatorContext cxt) {
if(phoneField == null) {
return false;
}
return phoneField.matches("^\d{13}$");
}
}

所有验证规则方法类都要实现ConstraintValidator<V,F>这个接口, 里面第一个方法initialize的参数是所关联的注解对象, 所以这个方法里可以取出使用注解的地方传进来的值, 后面一个例子会讲到这一点. 第二个最核心的方法isValid第一个参数就是我们要验证的字段值, 大家看下上面的代码就知道怎样使用了.

下面我们来看第二种形式的注解. 假如我们对用户的生日字段进行验证, 限制只满足1989年出生的人。 如下:

public class Person {
@Year(1989)
private Date birthday; // getters setters ... }

现在自定义验证注解Year有要传入一个参数, 用默认的value方法接收:

@Documented
@Constraint(validatedBy = YearConstraintValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Year { int value(); String message() default "{Year}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }

还是要上面的一样, 要定义一个规则约束描述类:

public class YearConstraintValidator implements ConstraintValidator<Year, Date> {

	private int annotationYear;

	@Override
public void initialize(Year year) {
this.annotationYear = year.value();
} @Override
public boolean isValid(Date target, ConstraintValidatorContext cxt) {
if(target == null) {
return true;
}
Calendar c = Calendar.getInstance();
c.setTime(target);
int fieldYear = c.get(Calendar.YEAR);
return fieldYear == annotationYear;
} }

可以看到initiallize方法中可以接收关联的注解Year, 这里可以取出里面的参数信息用于约束规则方法调用.

原文: http://www.javacodegeeks.com/2013/07/spring-mvc-custom-validation-annotations.html

[译]SpringMVC自定义验证注解(SpringMVC custom validation annotations)的更多相关文章

  1. springboot学习(二十二)_ 使用@Constraint注解自定义验证注解

    最近项目在使用如@NotNull @Max 等配合@vaild 注解进行验证传过来的参数校验,然后通过统一异常处理,直接返回给前端,不用在业务代码中对这些参数进行校验.但是官方提供的并不能全部满足项目 ...

  2. SpringBoot-表单验证-统一异常处理-自定义验证信息源

    1. 简介 我们都知道前台的验证只是为了满足界面的友好性.客户体验性等等.但是如果仅靠前端进行数据合法性校验,是远远不够的.因为非法用户可能会直接从客户端获取到请求地址进行非法请求,所以后台的校验是必 ...

  3. Hibernate validation 注解 springmvc 验证 分组

    SpringMVC验证框架Validation特殊用法   1. 分组 有的时候,我们对一个实体类需要有多中验证方式,在不同的情况下使用不同验证方式,比如说对于一个实体类来的id来说,保存的时候是不需 ...

  4. springMVC自定义注解实现用户行为验证

    最近在进行项目开发的时候需要对接口做Session验证 1.自定义一个注解@AuthCheckAnnotation @Documented @Target(ElementType.METHOD) @I ...

  5. SpringMVC 使用验证框架 Bean Validation(上)

    SpringMVC 使用验证框架 Bean Validation(上) 对于任何一个应用而言在客户端做的数据有效性验证都不是安全有效的,这时候就要求我们在开发的时候在服务端也对数据的有效性进行验证. ...

  6. springmvc 自定义注解

    1. 自定义一个注解 @Documented //文档生成时,该注解将被包含在javadoc中,可去掉 @Target(ElementType.METHOD)//目标是方法 @Retention(Re ...

  7. SpringMVC使用@Valid注解进行数据验证

    SpringMVC使用@Valid注解进行数据验证   from:https://blog.csdn.net/zknxx/article/details/52426771 我们在做Form表单提交的时 ...

  8. asp.net mvc 中的自定义验证(Custom Validation Attribute)

    前言

  9. SpringMVC数据验证

    SpringMVC数据验证——第七章 注解式控制器的数据验证.类型转换及格式化——跟着开涛学SpringMVC 资源来自:http://jinnianshilongnian.iteye.com/blo ...

随机推荐

  1. 转:Web页面通过URL地址传递参数常见问题及检测方法

    Web页面即我们在浏览器中所看到的网页,在Web应用程序中,其页面往往需要进行动态切换和数据交互,页面间的数据常规传递方法有多种,本文主要介绍Web页面处理程序中常见的URL地址参数传递方法,包括概述 ...

  2. HDU 4597 Play Game

    题目链接 什么都不想说,最近状态暴跌.. #include <cstdio> #include <cstring> #include <iostream> usin ...

  3. dubbo源码学习(一)之ExtensionLoader

    [转载请注明作者和原文链接,欢迎讨论,相互学习.] 一.前言 ExtensionLoader类,主要是根据扩展点名称来对扩展点接口实现进行的一系列操作,如果获取扩展点接口实现实例.适配类实例.更新实现 ...

  4. 20145330孙文馨 《Java程序设计》第一周学习总结

    20145330孙文馨 <Java程序设计>第一周学习总结 教材学习内容总结 刚开始拿到这么厚一本书说没有压力是不可能的,开始从头看觉得很陌生进入不了状态,就稍微会有一点焦虑的感觉.于是就 ...

  5. 实现Map-side Join和Reduce-side Join(转)

    在大数据处理场景中,多表Join是非常常见的一类运算.为了便于求解,通常会将多表join问题转为多个两表连接问题.两表Join的实现算法非常多,一般我们会根据两表的数据特点选取不同的join算法,其中 ...

  6. java线程的简单实现及方法

    java线程: 线程是一个程序内部的顺序控制流. cpu实际上在一个时间点上,只执行一个.只不过我们把cpu分成了多个时间片,由于速度很快,我们看起来像是多个线程.. 就像你的时间分成几片,这样 整体 ...

  7. [LintCode] Sort Integers II 整数排序之二

    Given an integer array, sort it in ascending order. Use quick sort, merge sort, heap sort or any O(n ...

  8. [LintCode] Move Zeroes 移动零

    Given an array nums, write a function to move all 0's to the end of it while maintaining the relativ ...

  9. Hadoop.2.x_伪分布环境搭建

    一. 基本环境搭建 1. 设置主机名.静态IP/DNS.主机映射.windows主机映射(方便ssh访问与IP修改)等 设置主机名: vi /etc/sysconfig/network # 重启系统生 ...

  10. JAVA 线程同步异步简单实例

    package test; public class testThread { public static void main(String[] args) { Example example = n ...