Java注解Annotation用起来很方便,也越来越流行,由于其简单、简练且易于使用等特点,很多开发工具都提供了注解功能,不好的地方就是代码入侵比较严重,所以使用的时候要有一定的选择性。
这篇文章将利用注解,来做一个Bean的数据校验。
下载
http://download.csdn.net/download/hanghangaidoudou/10139375
项目结构

定义注解
该注解可以验证成员属性是否为空,长度,提供了几种常见的正则匹配,也可以使用自定义的正则去判断属性是否合法,同时可以为该成员提供描述信息。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package org.xdemo.validation.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.xdemo.validation.RegexType;/** * 数据验证 * @author Goofy */@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD,ElementType.PARAMETER})public @interface DV { //是否可以为空 boolean nullable() default false; //最大长度 int maxLength() default 0; //最小长度 int minLength() default 0; //提供几种常用的正则验证 RegexType regexType() default RegexType.NONE; //自定义正则验证 String regexExpression() default ""; //参数或者字段描述,这样能够显示友好的异常信息 String description() default "";} |
注解的解析
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | package org.xdemo.validation.annotation.support;import java.lang.reflect.Field;import org.xdemo.validation.RegexType;import org.xdemo.validation.annotation.DV;import org.xdemo.validation.utils.RegexUtils;import org.xdemo.validation.utils.StringUtils;/** * 注解解析 * @author Goofy */public class ValidateService { private static DV dv; public ValidateService() { super(); } //解析的入口 public static void valid(Object object) throws Exception{ //获取object的类型 Class<? extends Object> clazz=object.getClass(); //获取该类型声明的成员 Field[] fields=clazz.getDeclaredFields(); //遍历属性 for(Field field:fields){ //对于private私有化的成员变量,通过setAccessible来修改器访问权限 field.setAccessible(true); validate(field,object); //重新设置会私有权限 field.setAccessible(false); } } public static void validate(Field field,Object object) throws Exception{ String description; Object value; //获取对象的成员的注解信息 dv=field.getAnnotation(DV.class); value=field.get(object); if(dv==null)return; description=dv.description().equals("")?field.getName():dv.description(); /*************注解解析工作开始******************/ if(!dv.nullable()){ if(value==null||StringUtils.isBlank(value.toString())){ throw new Exception(description+"不能为空"); } } if(value.toString().length()>dv.maxLength()&&dv.maxLength()!=0){ throw new Exception(description+"长度不能超过"+dv.maxLength()); } if(value.toString().length()<dv.minLength()&&dv.minLength()!=0){ throw new Exception(description+"长度不能小于"+dv.minLength()); } if(dv.regexType()!=RegexType.NONE){ switch (dv.regexType()) { case NONE: break; case SPECIALCHAR: if(RegexUtils.hasSpecialChar(value.toString())){ throw new Exception(description+"不能含有特殊字符"); } break; case CHINESE: if(RegexUtils.isChinese2(value.toString())){ throw new Exception(description+"不能含有中文字符"); } break; case EMAIL: if(!RegexUtils.isEmail(value.toString())){ throw new Exception(description+"地址格式不正确"); } break; case IP: if(!RegexUtils.isIp(value.toString())){ throw new Exception(description+"地址格式不正确"); } break; case NUMBER: if(!RegexUtils.isNumber(value.toString())){ throw new Exception(description+"不是数字"); } break; case PHONENUMBER: if(!RegexUtils.isPhoneNumber(value.toString())){ throw new Exception(description+"不是数字"); } break; default: break; } } if(!dv.regexExpression().equals("")){ if(value.toString().matches(dv.regexExpression())){ throw new Exception(description+"格式不正确"); } } /*************注解解析工作结束******************/ }} |
用到的几个类
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package org.xdemo.validation;/** * 常用的数据类型枚举 * @author Goofy * */public enum RegexType { NONE, SPECIALCHAR, CHINESE, EMAIL, IP, NUMBER, PHONENUMBER; } |
其中正则验证类和字符串工具类请参考以下链接:
-
SuperUtil之RegexUtils
-
SuperUtil之StringUtils
使用方法
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package org.xdemo.validation.test;import org.xdemo.validation.RegexType;import org.xdemo.validation.annotation.DV;public class User { @DV(description="用户名",minLength=6,maxLength=32,nullable=false) private String userName; private String password; @DV(description="邮件地址",nullable=false,regexType=RegexType.EMAIL) private String email; public User(){} public User(String userName, String password, String email) { super(); this.userName = userName; this.password = password; this.email = email; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }} |
测试代码
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package org.xdemo.validation.test;import org.xdemo.validation.annotation.support.ValidateService;/** * @author Goofy */public class Test { public static void main(String[] args){ User user=new User("张三", "xdemo.org", "252878950@qq.com"); try { ValidateService.valid(user); } catch (Exception e) { e.printStackTrace(); } user=new User("zhangsan","xdemo.org","xxx@"); try { ValidateService.valid(user); } catch (Exception e) { e.printStackTrace(); } user=new User("zhangsan","xdemo.org",""); try { ValidateService.valid(user); } catch (Exception e) { e.printStackTrace(); } }} |
运行效果
