Java注解Annotation用起來(lái)很方便,也越來(lái)越流行,由于其簡(jiǎn)單、簡(jiǎn)練且易于使用等特點(diǎn),很多開(kāi)發(fā)工具都提供了注解功能,不好的地方就是代碼入侵比較嚴(yán)重,所以使用的時(shí)候要有一定的選擇性。
這篇文章將利用注解,來(lái)做一個(gè)Bean的數(shù)據(jù)校驗(yàn)。
下載
http://pan.baidu.com/s/1mgn2AHa
**項(xiàng)目結(jié)構(gòu) **

43ebba26b760579b001bd0f2d6ec5e45.jpg
定義注解
該注解可以驗(yàn)證成員屬性是否為空,長(zhǎng)度,提供了幾種常見(jiàn)的正則匹配,也可以使用自定義的正則去判斷屬性是否合法,同時(shí)可以為該成員提供描述信息。
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;
/**
* 數(shù)據(jù)驗(yàn)證
* @author Goofy
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.PARAMETER})
public @interface DV {
//是否可以為空
boolean nullable() default false;
//最大長(zhǎng)度
int maxLength() default 0;
//最小長(zhǎng)度
int minLength() default 0;
//提供幾種常用的正則驗(yàn)證
RegexType regexType() default RegexType.NONE;
//自定義正則驗(yàn)證
String regexExpression() default "";
//參數(shù)或者字段描述,這樣能夠顯示友好的異常信息
String description() default "";
}
注解的解析
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的類(lèi)型
Class<? extends Object> clazz=object.getClass();
//獲取該類(lèi)型聲明的成員
Field[] fields=clazz.getDeclaredFields();
//遍歷屬性
for(Field field:fields){
//對(duì)于private私有化的成員變量,通過(guò)setAccessible來(lái)修改器訪(fǎng)問(wèn)權(quán)限
field.setAccessible(true);
validate(field,object);
//重新設(shè)置會(huì)私有權(quán)限
field.setAccessible(false);
}
}
public static void validate(Field field,Object object) throws Exception{
String description;
Object value;
//獲取對(duì)象的成員的注解信息
dv=field.getAnnotation(DV.class);
value=field.get(object);
if(dv==null)return;
description=dv.description().equals("")?field.getName():dv.description();
/*************注解解析工作開(kāi)始******************/
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+"長(zhǎng)度不能超過(guò)"+dv.maxLength());
}
if(value.toString().length()<dv.minLength()&&dv.minLength()!=0){
throw new Exception(description+"長(zhǎng)度不能小于"+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+"不是數(shù)字");
}
break;
case PHONENUMBER:
if(!RegexUtils.isPhoneNumber(value.toString())){
throw new Exception(description+"不是數(shù)字");
}
break;
default:
break;
}
}
if(!dv.regexExpression().equals("")){
if(value.toString().matches(dv.regexExpression())){
throw new Exception(description+"格式不正確");
}
}
/*************注解解析工作結(jié)束******************/
}
}
用到的幾個(gè)類(lèi)
package org.xdemo.validation;
/**
* 常用的數(shù)據(jù)類(lèi)型枚舉
* @author Goofy
*
*/
public enum RegexType {
NONE,
SPECIALCHAR,
CHINESE,
EMAIL,
IP,
NUMBER,
PHONENUMBER;
}
其中正則驗(yàn)證類(lèi)和字符串工具類(lèi)請(qǐng)參考以下鏈接:
使用方法
package org.xdemo.validation.test;
import org.xdemo.validation.RegexType;
import org.xdemo.validation.annotation.DV;
public class User {
@DV(description="用戶(hù)名",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;
}
}
測(cè)試代碼
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();
}
}
}
運(yùn)行效果

image.jpeg
轉(zhuǎn)載請(qǐng)注明來(lái)源:http://www.xdemo.org/java-annotation-validate/