基于注解校验

基于注解的方式校验其实很多,但是在复杂模型方式方面,貌似未查询到,所以自己写了一个,主要是复杂的json串,将其生成Object,然后对于Object校验...

注解申明不过于进行介绍,主要谈下配合反射进行递归校验过程,校验




 
 这里以UrlParser校验,当然接口提供后可以有无数个比如money、date、身份证等,

注解类

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidationDriver {
	public ValidationType type();
}

 

/**
 * 
 * @author Young
 *
 */
public enum ValidationType {
	// support multi type
	Length, Email, NotBlank, URL, Phone, Money, Date;
}

 

核心的校验过程

public static ValidateMsg validate(Object field) throws Exception {
		ValidateMsg result = null;
		for (Field f : field.getClass().getDeclaredFields()) {
			if (f.isAnnotationPresent(ValidationDriver.class)) {
				ValidationDriver driver = f
						.getAnnotation(ValidationDriver.class);
				f.setAccessible(true);
				Object value = null;
				try {
					value = f.get(field);
				} catch (IllegalArgumentException e) {
				} catch (IllegalAccessException e) {
				}
				IAnnotationParser parse = fetchValidateParser(driver);
				result = parse.validate(f, value);
				if (result != null && !result.isResult())
					break;
			} else if (f.getType().getName().contains("hundsun")) {
				result = recursiveCheck(field, f);
				if (result != null && !result.isResult())
					break;
			} else if (f.getType().getName().equals("java.util.List")) {
				// 获取泛型
				Type fc = f.getGenericType();
				f.setAccessible(true);
				if (fc == null) {
					continue;
				}
				Method m = (Method) field.getClass().getMethod(
						"get" + getMethodName(f.getName()));
				//当类型中是List,获取list的数据,再进行校验
				List list = (List) m.invoke(field);
				if (list != null && list.size() > 0) {
					for (Object object : list) {
						result = validate(object);
						if (result != null && !result.isResult())
							break;
					}
				}
				if (result != null && !result.isResult())
					break;
			}
		}
		if (result == null) {
			result = new ValidateMsg();
			result.setMessage("everything is ok");
		}
		return result;
	}

	/**
	 * 递归校验
	 * 
	 * @param field
	 * @param f
	 * @return
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws InstantiationException
	 * @throws IllegalArgumentException
	 */
	private static ValidateMsg recursiveCheck(Object field, Field f)
			throws Exception {
		ValidateMsg result = null;
		f.setAccessible(true);
		Field[] fields = f.getType().getDeclaredFields();
		for (Field fieldSon : fields) {
			if (fieldSon.isAnnotationPresent(ValidationDriver.class)) {
				ValidationDriver driver = fieldSon
						.getAnnotation(ValidationDriver.class);
				fieldSon.setAccessible(true);
				Object valSon = fieldSon.get(f.get(field));
				IAnnotationParser parse = fetchValidateParser(driver);
				result = parse.validate(fieldSon, valSon);
				if (result != null && !result.isResult())
					break;
			} else if (fieldSon.getType().getName().equals("java.util.List")) {
				// 获取泛型
				Type fc = fieldSon.getGenericType();
				fieldSon.setAccessible(true);
				if (fc == null) {
					continue;
				}
				Method m = (Method) f.get(field).getClass()
						.getMethod("get" + getMethodName(fieldSon.getName()));
				List list = (List) m.invoke(f.get(field));
				if (list != null && list.size() > 0) {
					for (Object object : list) {
						result = validate(object);
						if (result != null && !result.isResult())
							break;
					}
				}
			}
		}
		return result;
	}

	private static String getMethodName(String fildeName) throws Exception {
		byte[] items = fildeName.getBytes();
		items[0] = (byte) ((char) items[0] - 'a' + 'A');
		return new String(items);
	}

 上述方式支持

public class A{
@ValidationDriver(type = ValidationType.NotBlank)
private int age;
private List<B> list;
get/set
}

public class B{
@ValidationDriver(type = ValidationType.NotBlank)
private int id;
private List<C> list
get/set
}

public class C{
@ValidationDriver(type = ValidationType.NotBlank)
private int id;
@ValidationDriver(type = ValidationType.URL)
private String name;
}

 最终URLparser校验

public class UrlParser implements IAnnotationParser {
	@Override
	public ValidateMsg validate(Field field, Object value) {
		ValidateMsg msg = null;
		if (value != null) {
			Pattern p = Pattern
					.compile(
							"^(http|www|ftp|)?(://)?(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*((:\\d+)?)(/(\\w+(-\\w+)*))*(\\.?(\\w)*)(\\?)?(((\\w*%)*(\\w*\\?)*(\\w*:)*(\\w*\\+)*(\\w*\\.)*(\\w*&)*(\\w*-)*(\\w*=)*(\\w*%)*(\\w*\\?)*(\\w*:)*(\\w*\\+)*(\\w*\\.)*(\\w*&)*(\\w*-)*(\\w*=)*)*(\\w*)*)$",
							Pattern.CASE_INSENSITIVE);
			Matcher m = p.matcher(value.toString());
			if (!m.matches()) {
				msg = new ValidateMsg();
				msg.setMessage(field.getName() + " url is invalid");
				msg.setResult(false);
			}
		}
		return msg;
	}

}

 

结论:

能够支持多种复杂类型,然后进行成员变量的校验,基本能够完成其校验工作。通过学习反射了解到很多知识点,弥补过多if else判断,当然这里其实校验过程也可以使用antlr方式进行表达式强校验,可以查阅我其它文章。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值