开发过程中,难免会对数据进行校验或处理,难道每次都对不同的实体类的属性挨个判断是否符合规范或者对其进行特殊处理,程序员不应该这么做。在这个时候,自定义注解就派上大用场了。比如自定义一个 @Email 注解,将其标注在只能存放email格式的属性(private String guestEmail)上,再在程序入口上加一个判断工具类。那么程序将利用你事先写好的方法进行校验该属性值是否符合邮件的格式,并进行相应处理。废话不多说,看看下面的轮子吧。(注:文末付完整工具类链接)
1、定义@Email 注解
package java1.lang.annotation.validation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author zxiaofan 邮件地址,该注解只能String使用
*
*/
@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Email {
}
2、构建校验工具类ValidationUtils
package java1.lang.annotation.validation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author github.zxiaofan.com
*
* 用于参数校验
*/
@SuppressWarnings({"rawtypes", "unused", "unchecked"})
public final class ValidationUtils {
/**
* regex_Email.
*/
private static final String REGEXMAIL = "^\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+$";
/**
* 构造函数.
*
*/
private ValidationUtils() {
throw new RuntimeException("this is a util class,can not instance!");
}
/**
* 参数校验.
*
* @param obj
* obj
* @return obj
* @throws Exception
* e
*/
public static String validate(Object obj) throws Exception {
List<String> list = new ArrayList<String>();
if (null == obj) {
return "参数为null";
}
Field[] fields = obj.getClass().getDeclaredFields();
long now = System.currentTimeMillis();
String claName = obj.getClass().getName();
for (Field field : fields) {
realValidate(obj, list, now, claName, field);
}
return list.isEmpty() ? null : packaging(list);
}
/**
* 添加方法注释.
*
* @param list
* 结果
* @return 结果
*/
private static String packaging(List<String> list) {
StringBuffer sb = new StringBuffer();
for (String s : list) {
sb.append(s).append(';');
}
sb.setLength(sb.length() - 1);
return sb.toString();
}
/**
* 对指定注解进行校验.
*
* @param obj
* 参数
* @param list
* 结果
* @param now
* 当前时间
* @param claName
* 类名
* @param field
* 属性
* @throws Exception
* e
*/
private static void realValidate(Object obj, List<String> list, long now, String claName, Field field) throws Exception {
Email email;
FutureTime futureTime;
StringLength stringLength;
PastTime pastTime;
Pattern pattern;
Phone phone;
PostalCode postalCode;
Tel tel;
NotNullAndEmpty nullAndEmpty;
Number number;
ToLower lower;
ToUpper upper;
Date date;
Object value;
String fieldName;
Class type;
boolean isNotNull;
type = field.getType();
fieldName = field.getName();
Annotation[] annotations = field.getAnnotations();
field.setAccessible(true);
value = field.get(obj);
isNotNull = field.isAnnotationPresent(NotNull.class);
for (Annotation an : annotations) {
if (an.annotationType().getName().equals(Email.class.getName())) { // 有email注解
validateEmail(list, claName, field, value, fieldName, type, isNotNull, an);
}
}
field.setAccessible(false);
email = null;
}
/**
* 校验email.
*
* @param list
* 结果
* @param claName
* 类型
* @param field
* 属性
* @param value
* 属性值
* @param fieldName
* 属性名称
* @param type
* 类型
* @param an
* 注解
* @param isNotNull
* 不能为空
* @throws Exception
* e
*/
private static void validateEmail(List<String> list, String claName, Field field, Object value, String fieldName, Class type, boolean isNotNull, Annotation an) throws Exception {
Email email;
email = (Email) an;
if (String.class.equals(type)) {
if (isNotNull) {
if (null == value || !value.toString().matches(REGEXMAIL)) {
list.add("参数:[" + field.getName() + "]必须是邮箱地址;格式为:" + REGEXMAIL);
}
} else {
if (null != value && !value.toString().matches(REGEXMAIL)) {
list.add("参数:[" + field.getName() + "]必须是邮箱地址;格式为:" + REGEXMAIL);
}
}
} else {
throw new Exception(claName + "类中字段[" + fieldName + "]注解:validation.Email只能使用在java.lang.String上");
}
}
}
3、工具类的使用
首先定义一个javaBean
package java1.lang.annotation;
import java1.lang.annotation.validation.AssertFalse;
import java1.lang.annotation.validation.Email;
import java1.lang.annotation.validation.StringCut;
import java1.lang.annotation.validation.ToUpper;
&