`
cywhoyi
  • 浏览: 421202 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

基于注解校验

    博客分类:
  • JAVA
阅读更多

基于注解的方式校验其实很多,但是在复杂模型方式方面,貌似未查询到,所以自己写了一个,主要是复杂的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方式进行表达式强校验,可以查阅我其它文章。

  • 大小: 13.2 KB
  • 大小: 20.8 KB
1
3
分享到:
评论

相关推荐

    自定义校验注解框架(validator)

    自定义校验注解框架(Validator)是一种在Java开发中常用的技术,用于增强代码的健壮性和可维护性。在实际项目中,我们经常需要对输入的参数进行有效性检查,如非空验证、数据类型验证、长度验证等。自定义注解框架...

    基于校验器链的简单实现,支持对象按照属性来自定义校验,可以重用校验器。

    总的来说,基于校验器链的实现为Java开发者提供了一种优雅的处理数据验证的方式,它通过注解和反射简化了代码,提高了代码的可读性和可维护性。同时,通过校验器的复用,可以有效地减少重复工作,提升开发效率。在...

    基于Annotation写的简单数据校验框架

    在工作中,我看到JavaEE6中提供了一个基于注解的Bean校验框架,另外Hibernate也提供了类似功能的基于java注解的校验,我们产品也需要这种功能,无奈用的是JavaEE5,因此我自己写了一个简单的基于注解的校验框架,...

    注解+反射实现自定义验证工具,可实现业务校验,字段多种校验

    本文介绍了一种基于注解和反射技术实现自定义验证工具的方法,该方法具有很好的扩展性和可维护性。通过自定义注解和枚举,可以轻松地为不同类型的字段定义多种验证规则,并且可以通过反射动态地执行这些规则。这种...

    Hibernate Validation自定义注解校验的实现

    Hibernate Validation是Java Bean Validation API的实现,提供了一种基于注解的校验机制。它允许开发者使用注解来定义校验规则,然后使用Validator来进行校验。 在实现自定义注解校验时,我们需要定义一个自定义的...

    SpringBoot+SpringSecurity+JWT+MybatisPlus实现基于注解的权限验证

    SpringBoot+SpringSecurity+JWT+MybatisPlus实现基于注解的权限验证,可根据注解的格式不同,做到角色权限控制,角色加资源权限控制等,粒度比较细化。 @PreAuthorize("hasAnyRole('ADMIN','USER')"):具有admin或...

    struts2的数据校验

    Struts2提供了多种数据校验方式,包括基于注解的校验、基于XML配置的校验和自定义校验。 1. **基于注解的校验**: Struts2集成Spring的Validation框架,允许开发者在Action类的属性上使用JSR303/JSR349(Bean ...

    注解+AOP优雅的实现java项目的接口参数校验(含源码)

    基于Spring boot + maven,以注解+AOP方式实现的java后端项目接口参数校验框架。迄今为止使用最简单、最容易理解的参数校验方案。博客地址:https://blog.csdn.net/weixin_42686388/article/details/104009771

    Struts2自定义校验框架

    它支持两种验证方式:基于注解的验证(Annotation-based Validation)和基于XML的验证(XML-based Validation)。自定义校验主要是通过编写自定义校验器或扩展内置校验器来实现。 2. **自定义校验器实现** 自定义...

    Clairvoyant 基于注解的Android自动校验框架.zip

    Android是一种基于Linux内核(不包含GNU组件)的自由及开放源代码的移动操作系统,主要应用于移动设备,如智能手机和平板电脑。该系统最初由安迪·鲁宾开发,后被Google公司收购并注资,随后与多家硬件制造商、软件...

    CRC16校验计算器

    CRC16校验计算器是一种用于数据完整性检查的工具,它基于CRC(循环冗余校验)算法,广泛应用于通信、存储等领域。CRC16能够检测出传输或存储数据中的单比特或多比特错误,确保数据在传输过程中的准确无误。 在C# ...

    Struts2 校验器

    Struts2的校验框架是基于Apache Commons Validator库的,它允许开发者定义一系列的验证规则来检查用户的输入。这些规则可以是简单的数据类型检查,如非空、长度限制,也可以是复杂的业务逻辑校验。校验过程通常分为...

    struts2输入校验深入总结

    Struts2提供了多种方式进行输入校验,包括Action级别校验、拦截器级别校验以及基于Validator框架的校验。 二、Action级别校验 Action级别校验是在Action类中定义校验逻辑,通常通过在Action类的属性上添加注解实现...

    基于JavaBean元数据的final-validator校验模型与自定义注解设计源码

    本项目为基于JavaBean元数据的final-validator校验模型与自定义注解设计,包含92个文件,其中包括72个Java源文件、7个Markdown文档、5个XML配置文件、2个属性文件、1个Git忽略文件、1个LICENSE文件和其他相关文件。...

    struts2笔记之校验表单信息

    Struts2是一个流行的Java Web框架,它提供了丰富的功能来帮助开发者构建动态Web应用程序。...无论是使用XML配置文件、注解还是自定义校验方法,都能有效地实现表单数据的验证,为Java Web开发带来了极大的便利。

    自动校验工程源码

    本文将围绕“自动校验工程源码”这一主题,深入探讨基于反射的自动校验工具类及其相关知识点。 首先,我们要理解什么是反射。在Java等面向对象的编程语言中,反射是一种强大的机制,它允许程序在运行时检查和修改...

    非常好用的后台校验 jar包

    这些校验器可能基于如JSR 303/349(Java Bean Validation)这样的标准,或者是一个自定义实现。 在实际应用中,开发者可以简单地引入这个jar包,并在控制器层的方法参数上使用对应的校验注解,然后在服务层调用校验...

    oval 校验 工具包

    它不仅支持基本的数据类型校验,还能处理复杂的业务逻辑验证,比如基于对象关系的校验。此外,OVAL的校验结果可以与其他框架(如Spring MVC)集成,以便在验证失败时返回友好的错误信息给用户。 总的来说,OVAL是一...

    struts2输入校验

    Struts2提供了内置的验证框架,基于XML配置或者注解实现。这个框架允许开发者定义一组规则来检查用户提交的数据,这些规则可以在Action类中应用。 2. **XML输入校验**: - **创建校验文件**:首先,你需要创建一...

    一个既简单的校验框架

    本篇将深入探讨一个基于Java的简单校验框架的实现,该框架充分利用了注解和反射技术,旨在提供一种优雅且可扩展的解决方案。 首先,我们来理解注解(Annotation)在Java中的作用。注解是一种元数据,它提供了在源...

Global site tag (gtag.js) - Google Analytics