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
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();
}
}
}
|
运行效果