`

字段校验

 
阅读更多
今天研究一下本公司系统中字段验证的子系统,本博文方便日后回看。

主要的技术,包括自定义注解、反射


自定义注解,如下:最大长度注解
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MaxLength {
	/**
	 * <b>方法说明:</b>
	 * <ul>
	 * 最大长度
	 * </ul>
	 * @return 
	 */
	int value();
}


编写实体类,在字段上填加自定义注解
	@MaxLength(value = 12)
	private String id;


创建n个对象,封装到list中,进行遍历,通过单例模式,获取数据验证引擎,执行校验方法。

校验方法:
	/** 数据验证实现类集合 */
	private List<IDataValidate> dataValidateList;

	 /**
	 * <b>方法说明:</b>
	 * <ul>
	 * 执行数据验证
	 * </ul>
	 * @param validateObject 需要验证的数据类对象
	 * @param fieldStartNum 字段起始位
	 * @return 验证失败信息
	 */
	public String validate(Object validateObject, int fieldStartNum) {
		StringBuilder result = new StringBuilder();

		DataValidationMemory memory = DataValidationMemory.getInstance();

		//类名
		Class<?> className = validateObject.getClass();
		//类的注解字段信息
		Map<Class<? extends Annotation>, Map<Field, Annotation>> objectAnnotationFieldMap = memory.getObjectAnnotationFieldMap(className);

		//如果内存中不存在此类的注解字段信息,则初始化
		if (objectAnnotationFieldMap == null) {
			memory.initObjectField(validateObject.getClass(), fieldStartNum);
		}

		if (dataValidateList == null || dataValidateList.size() <= 0) {
			throw new GnntException("注解验证实现类集合为空");
		}

		//循环此类的所有数据验证实现类,执行其注解验证方法
		for (IDataValidate dataValidate : dataValidateList) {
			result.append(dataValidate.validate(validateObject));
		}

		return result.toString();
	}

dataValidateList来源:通过spring.xml注入,通过遍历接口,实现循环注解的校验。
DataValidationMemory:数据验证内存类.

public class DataValidationMemory {
	/** 数据验证内存类 */
	private static DataValidationMemory memory;

	/** 
	 * 数据验证类对象的注解字段集合
	 * 数据类,注解类,字段注解对象
	 */
	private Map<Class<?>, Map<Class<? extends Annotation>, Map<Field, Annotation>>> objectAnnotationFieldMap = new ConcurrentHashMap<Class<?>, Map<Class<? extends Annotation>, Map<Field, Annotation>>>();
	/** 数据验证类对象的字段集合 */
	private Map<Class<?>, List<Field>> objectFieldMap = new ConcurrentHashMap<Class<?>, List<Field>>();


	/**
	 * <b>方法说明:</b>
	 * <ul>
	 * 初始化数据验证类字段
	 * </ul>
	 * @param objectClass 数据验证类
	 * @param fieldStartNum 字段起始位
	 */
	public synchronized void initObjectField(Class<?> objectClass, int fieldStartNum) {
		if (objectClass == null) {
			throw new GnntException("需要数据验证的类为空");
		}
		if (fieldStartNum <= 0) {
			throw new GnntException("字段起始位不能为负值");
		}

		//注解字段信息集合
		Map<Class<? extends Annotation>, Map<Field, Annotation>> fieldAnnotationMap = new HashMap<Class<? extends Annotation>, Map<Field, Annotation>>();
		//字段集合
		List<Field> fieldList = new ArrayList<Field>();

		//类中所有字段信息
		Field[] objectClassFields = objectClass.getDeclaredFields();
		//循环此类所有的字段信息,初始化其注解配置
		for (int i = (fieldStartNum - 1); i < objectClassFields.length; i++) {
			Field field = objectClassFields[i];
			//解决字段是private修饰符无法获取字段信息问题
			if (!field.isAccessible()) {
				field.setAccessible(true);
			}

			//循环所有的注解
			Annotation[] fieldAnnotations = field.getAnnotations();
			if (fieldAnnotations != null) {
				for (Annotation annotation : fieldAnnotations) {
					//字段对应的注解信息集合
					Class<? extends Annotation> annotationType = annotation.annotationType();
					Map<Field, Annotation> annotationMap = fieldAnnotationMap.get(annotationType);
					//如果该注解类不存在,则创建
					if (annotationMap == null) {
						annotationMap = new HashMap<Field, Annotation>();
					}

					if (annotationMap.containsKey(field)) {
						throw new GnntException("同一字段不允许出现重复注解");
					}

					annotationMap.put(field, annotation);
					fieldAnnotationMap.put(annotationType, annotationMap);
				}
				fieldList.add(field);
			}
		}
		objectAnnotationFieldMap.put(objectClass, fieldAnnotationMap);
		objectFieldMap.put(objectClass, fieldList);
	}
}

附件中为objectAnnotationFieldMap的debug结果,数据类,注解类,字段注解对象
objectFieldMap:数据类,字段list

	public StringBuilder validate(Object validateObject) {
		StringBuilder result = new StringBuilder();

		try {
			//获取数据验证类对象的字段集合
			Map<Class<? extends Annotation>, Map<Field, Annotation>> objectAnnotationFieldMap = DataValidationMemory.getInstance().getObjectAnnotationFieldMap(validateObject.getClass());
			Map<Field, Annotation> fieldAnnotationMap = objectAnnotationFieldMap.get(MaxLength.class);
			if (fieldAnnotationMap == null) {
				return result;
			}

			Set<Field> fieldSet = fieldAnnotationMap.keySet();
			//循环该注解的所有字段验证
			for (Field field : fieldSet) {
				try {
					Annotation annotation = fieldAnnotationMap.get(field);
					Object fieldValue = field.get(validateObject);
					if (fieldValue != null) {
						result.append(this.dealValidate(field, annotation, fieldValue.toString()));
					}
				} catch (Exception e) {
					GnntLogUtil.operationLogger.error("选项验证,系统异常", e);
					result.append("字段[").append(field.getName()).append("]验证异常");
				}
			}
		} catch (Exception e) {
			GnntLogUtil.operationLogger.error("选项验证,系统异常", e);
			result.append("注解[").append(MaxLength.class).append("]验证异常");
		}

		return result;
	}





	/**
	 * <b>方法说明:</b>
	 * <ul>
	 * 执行注解验证
	 * </ul>
	 * @param field 字段对象
	 * @param annotation 注解
	 * @param fieldValue 字段值
	 * @return 验证结果
	 */
	private StringBuilder dealValidate(Field field, Annotation annotation, String fieldValue) {
		StringBuilder result = new StringBuilder();

		if (annotation == null) {
			return result;
		}

		int value = ((MaxLength) annotation).value();
		if (value < 0) {
			throw new GnntException("注解值不能为负数");
		}

		if (fieldValue != null && fieldValue.length() > 0) {
			if (fieldValue.length() > value) {
				result.append("字段[").append(field.getName()).append("]值[").append(fieldValue).append("]值超长;");
			}
		}

		return result;
	}
  • 大小: 126.5 KB
分享到:
评论

相关推荐

    jsp字段校验与非字段校验

    **JSP字段校验与非字段校验** 在Web开发中,数据验证是必不可少的一环,它可以确保用户输入的数据符合应用程序的要求,防止错误的数据进入系统。JSP(JavaServer Pages)作为Java EE平台上的动态网页技术,提供了...

    字段校验规范.doc 规则

    字段校验规范.doc 规则

    .net实体类字段校验

    .net实体类字段校验,通过Attribute属性自定义校验、及错误信息。可校验字段长度,字段类型通过校验函数校验,统一校验 [TypeCheck(Name = "", Message = "请选择开始时间", Validate = ValidateUtils._DateTime)] ...

    【java框架】SpringBoot(9) -- Springboot中如何优雅的进行字段校验(csdn)————.pdf

    【SpringBoot字段校验】在SpringBoot应用中,优雅地执行字段校验是确保系统数据安全性和用户体验的关键步骤。本文将介绍如何利用SpringBoot集成的Hibernate Validate库进行字段校验,以及SpringBoot中的一些最佳实践...

    电信计费 字段校验 时长计算

    ### 电信计费系统中的字段校验与时长计算 电信计费系统是电信运营商的核心业务之一,它涉及到对大量的通话记录进行处理、分析与计费。在这一过程中,字段校验与时长计算是非常重要的两个环节。通过对这些数据的有效...

    5G网优案例:传输IPV6分片报文Reserved字段校验不通过导致VONR呼叫失败.docx

    ### 5G网络优化案例分析:传输IPV6分片报文Reserved字段校验问题 #### 背景概述 随着5G网络在全球范围内的普及和VoNR(Voice over New Radio)技术的大规模商用,运营商面临着诸多挑战。其中一项关键挑战就是确保...

    我的导入校验项目excel导入校验

    3. **数据有效性**:对特定字段进行校验,如手机号码、身份证号、邮箱等,确保其符合预设的格式规则。 4. **数据范围校验**:检查数值型数据是否在预设范围内,防止超出界限的数据导入。 5. **重复数据检查**:...

    关于java中对象属性值的校验的思考

    在Java编程中,对象属性值的校验是一个重要的实践环节,它确保了程序的数据完整性,防止因非法数据导致的运行时错误。这篇文章将探讨如何在Java中进行对象属性值的校验,以及相关的工具和源码分析。 首先,对象属性...

    使用Angular自定义字段校验指令的方法示例

    在Angular框架中,自定义字段校验指令是扩展表单验证功能的一种有效方式。当内置的验证器无法满足特定需求,例如对IP地址或MAC地址等特殊格式的数据进行验证时,开发者可以创建自己的验证指令。本文将详细讲解如何在...

    Springboot中如何优雅的进行字段校验.zip

    计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习...

    Struts2输入校验总结

    字段校验器直接作用于特定字段,而非字段校验器可以跨多个字段工作。 - 字段校验器配置示例: ```xml 被校验的字段"&gt; 校验器名"&gt; &lt;!-- 校验规则 --&gt; 参数名"&gt;参数值 &lt;!-- 错误信息 --&gt; 校验失败后的提示...

    struts2笔记之校验表单信息

    字段校验配置直接关联到Action中的属性,而非字段校验配置则需要显式指定被校验的字段名。还可以通过添加`short-circuit="true"`属性实现短路校验,即只显示第一个错误信息。 **二、基于Annotation的输入校验** ...

    CRC校验源代码(C#)

    1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。  2、生成CRC码的基本原理:任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’...

    struts2中的输入校验

    配置文件内容包括字段校验(field validation)和非字段校验(validator validation)。 - **全局校验配置文件**:全局校验配置文件(如`ActionName-validation.xml`)位于Action类同级目录下,对Action类的所有...

    struts2输入校验总结

    字段校验器针对Action类的某个属性进行校验,而非字段校验器则不直接关联具体属性,而是基于某些条件对多个字段进行校验。 #### 字段校验器配置示例: ```xml 被校验的字段"&gt; 校验器名"&gt; 参数名"&gt;参数值 ... ...

    MODBUS协议CRC校验原理

    CRC 码是数据通信领域中最常用的差错校验码,其特征是信息字段和校验字段的长度可以任意选定。CRC 码可以检测出数据传输中的错误,从而确保数据的正确性。 二、生成 CRC 码的基本原理 任意一个由二进制位串组成的...

    填报校验-数据是否重复.cpt

    帆软报表填报校验,数据插入时判断插入数据是否和数据库数据是否重复,不重复则插入,重复则显示提示信息“数据插入重复,请检查”,反之则插入成功,报表页面显示插入数据。

    统一接口解密封装校验参数测试用例

    统一接口解密封装校验参数测试用例

    springmvc数据验证

    Spring MVC 是一个强大的Java web应用程序框架,用于构建高效、可维护的Web应用。它整合了Spring框架的功能,提供了模型-视图-控制器(MVC)架构模式,使得开发者可以更专注于业务逻辑,而不是底层实现。...

    struts2 对action中的所有方法进行校验

    3. 动态字段校验: 对于动态或者复杂的数据校验需求,Struts2允许在运行时根据不同的请求参数选择不同的校验规则。这可以通过在validate()方法内进行条件判断来实现。 4. 国际化: Struts2支持国际化校验错误消息...

Global site tag (gtag.js) - Google Analytics