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;
     
}

其中正则验证类和字符串工具类请参考以下链接:

  1. SuperUtil之RegexUtils

  2. 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();
        }
    }
}

运行效果

Java注解Annotation 完成验证相关推荐

  1. Java注解(Annotation)详解

    转: Java注解(Annotation)详解 幻海流心 2018.05.23 15:20 字数 1775 阅读 380评论 0喜欢 1 Java注解(Annotation)详解 1.Annotati ...

  2. java注释和注解_深入理解JAVA注解(Annotation)以及自定义注解

    Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制.Java 语言中的类.方法.变量.参数和包等都可以被标注.注解可以看作是一种特殊的标记,在程序在编译或 ...

  3. java 注解: Annotation

    java 注解: Annotation 普通注解 自定义注解 元注解 注解: 位于源码中,用来修饰程序的元素,但不会对被修饰的对象有直接的影响. 可增加程序的动态性. 普通注解 普通注解:为java代 ...

  4. Java注解annotation invalid type of annotation member

    文章目录 Java注解annotation : invalid type of annotation member 1.什么是invalid type of annotation member 2.哪 ...

  5. Java 注解(Annotation)使用方法归纳

    Java注解Annotation使用方法归纳 简介 注解是从JDK5开始支持,是Java对元数据的一种特殊支持.与注释有一定区别,可以理解为代码上的特殊标记,通过这些标记我们可以在编译,类加载,运行等 ...

  6. Java 注解 Annotation

    概述 了解 Java 注解前必须先了解元注解. 元注解:描述注解的注解. 如果明白元数据概念就比较好理解元注解 元数据:描述数据的数据. 还是比较抽象哈,下面举个例子说明下. 比如一个txt文件的元数 ...

  7. 彻底搞懂Java注解Annotation(含注解的定义 原则 作用)

    注解的定义 定义 注解:提供一种为程序元素设置元数据的方法. 基本原则:注解不能直接干扰程序代码的运行,无论增加或删除注解,代码都能够正常运行. 注解(也被成为元数据)为我们在代码中添加信息提供了一种 ...

  8. 深入理解Java注解Annotation之注解处理器

    如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了.使用注解的过程中,很重要的一部分就是创建于使用注解处理器.Java SE5扩展了反射机制的API,以帮助程序员快速的构造自定义注解处 ...

  9. 深入理解Java注解Annotation及自定义注解

    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...

最新文章

  1. Tomcat6 内存和线程配置
  2. 刷题_thinkinginjava_吸血鬼数字
  3. 如何实现electron多页面间通信
  4. shell之实战应用一(查找xml文档中的关键字段)
  5. mysql cmd终端服务无法启动
  6. 米农分享:浅谈好域名应具备的10大特点
  7. 基于.Net + SqlServer的分库分表设计方案
  8. paip.哈米架构CAO.txt
  9. vue使用命令行构建完项目后_vue-cli起项目步骤(示例代码)
  10. 全面综合的管理平台,让所有网络都有管理员
  11. CSS3特效,跳动的心
  12. 元宇宙需要“基建狂魔”
  13. 计算机组装与维修第3版,计算机组装与维护(第3版)
  14. 不灭鸿蒙等级划分,等级划分
  15. 简单的省市区级联SQL脚本
  16. SQL语句中查找字符的位置
  17. 堆叠自动编码器(Stacked AutoEncoder)
  18. 九大数据分析方法:结构分析法
  19. 跌停的奥飞娱乐 在“盲盒“市场上还有一席之地吗?
  20. python bluetooth蓝牙信息获取蓝牙设备类型

热门文章

  1. 操作系统上机作业--使用条件变量解决生产者、计算者、消费者问题(多线程)
  2. linux査 到漠河 装apache,如何在Ubuntu上搭建一台安全的Apache Web服务器
  3. seqlist插入java_大话数据结构(五)(java程序)——顺序存储结构的插入与删除...
  4. ubuntu路由器联网_路由器及其协议简介| 联网
  5. 面向对象(封装对象private关键字)
  6. read/fread write/fwrite 的区别
  7. ijkplayer 消息循环处理过程分析
  8. 80. 删除排序数组中的重复项 II golang
  9. PyCharm安装好vim后,怎么配置.vimrc
  10. androidstudio 日历视图怎么显示农历_中秋国庆旅游攻略怎么做?用这个便签软件很简单...