- 浏览: 71322 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (113)
- oracle数据 (2)
- eclipse (3)
- 工具类使用 (14)
- 分隔符 (1)
- socket (1)
- ServletContextListener (1)
- String (3)
- StringUtils工具类 (2)
- springboot拦截器 (1)
- 页面 (2)
- map (1)
- 密码加密 (3)
- 缓存 (1)
- 文件上传 (1)
- 算法 (3)
- jquery (1)
- DateFormatUtils (1)
- xml (2)
- ftp (1)
- 接口 (3)
- 公钥私钥 (1)
- sigar (1)
- 前端 (2)
- lang3 (1)
- 定时器 (1)
- java基础 (13)
- javaBean (1)
- 工具类 (2)
- 插件 (1)
- 数据库 (2)
- 项目 (4)
- springboot (6)
- java集合 (1)
- 测试 (1)
- thymeleaf (3)
- mysql (7)
- 分布式 (1)
- idea (1)
- TCP (1)
- 微服务 (1)
- 高并发 (3)
- redis (1)
- 多线程 (2)
- SpringCloud (1)
- spring (1)
- 1111 (0)
- 开源 (1)
- npm (1)
最新评论
今天研究一下本公司系统中字段验证的子系统,本博文方便日后回看。
主要的技术,包括自定义注解、反射
自定义注解,如下:最大长度注解
编写实体类,在字段上填加自定义注解
创建n个对象,封装到list中,进行遍历,通过单例模式,获取数据验证引擎,执行校验方法。
校验方法:
dataValidateList来源:通过spring.xml注入,通过遍历接口,实现循环注解的校验。
DataValidationMemory:数据验证内存类.
附件中为objectAnnotationFieldMap的debug结果,数据类,注解类,字段注解对象
objectFieldMap:数据类,字段list
主要的技术,包括自定义注解、反射
自定义注解,如下:最大长度注解
@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; }
发表评论
-
幂等性
2020-06-28 19:17 301幂等性的 6 种实现方式,包括前端拦截、数据库悲观锁实现、数据 ... -
List如何一边遍历,一边删除?
2020-06-10 12:21 532主要有以下3种方法: 使用Iterator的remove ... -
Java 泛型中的通配符 T,E,K,V,?
2020-05-25 13:52 374本质上这些个都是通配符,没啥区别,只不过是编码时的一种约定俗 ... -
Java泛型中E、T、K、V等的含义
2020-05-12 16:31 788Java泛型中的标记符含义: ——————————————— ... -
java中的标记接口(标签接口)
2020-04-29 15:00 633Java中的标记接口(Marker ... -
防止页面被iframe嵌入
2019-04-17 20:07 429if (window != top){ top.lo ... -
在tomcat下context.xml中配置各种数据库连接池(JNDI)
2019-04-17 20:02 584Tomcat6的服务器配置文件放在 ${tomcat6}/ ... -
indexOf
2019-04-15 20:20 347indexOf(int,ch) ... -
equals与equalsIgnoreCase
2019-04-15 20:16 574String fileName=".SHP" ... -
JAVA中字符串比较equals()和equalsIgnoreCase()的区别
2018-04-10 13:54 6331、使用equals( )方法比较两个字符串是否相等。它具有如 ... -
Java system.getproperty获取环境属性
2018-04-18 10:56 466序号 属性 说明 1 java.version Java 运行 ... -
HashMap遍历的两种方式,推荐使用entrySet()
2018-01-12 13:37 2965第一种: Map map = new HashMap(); ...
相关推荐
**JSP字段校验与非字段校验** 在Web开发中,数据验证是必不可少的一环,它可以确保用户输入的数据符合应用程序的要求,防止错误的数据进入系统。JSP(JavaServer Pages)作为Java EE平台上的动态网页技术,提供了...
字段校验规范.doc 规则
.net实体类字段校验,通过Attribute属性自定义校验、及错误信息。可校验字段长度,字段类型通过校验函数校验,统一校验 [TypeCheck(Name = "", Message = "请选择开始时间", Validate = ValidateUtils._DateTime)] ...
【SpringBoot字段校验】在SpringBoot应用中,优雅地执行字段校验是确保系统数据安全性和用户体验的关键步骤。本文将介绍如何利用SpringBoot集成的Hibernate Validate库进行字段校验,以及SpringBoot中的一些最佳实践...
### 电信计费系统中的字段校验与时长计算 电信计费系统是电信运营商的核心业务之一,它涉及到对大量的通话记录进行处理、分析与计费。在这一过程中,字段校验与时长计算是非常重要的两个环节。通过对这些数据的有效...
### 5G网络优化案例分析:传输IPV6分片报文Reserved字段校验问题 #### 背景概述 随着5G网络在全球范围内的普及和VoNR(Voice over New Radio)技术的大规模商用,运营商面临着诸多挑战。其中一项关键挑战就是确保...
3. **数据有效性**:对特定字段进行校验,如手机号码、身份证号、邮箱等,确保其符合预设的格式规则。 4. **数据范围校验**:检查数值型数据是否在预设范围内,防止超出界限的数据导入。 5. **重复数据检查**:...
在Java编程中,对象属性值的校验是一个重要的实践环节,它确保了程序的数据完整性,防止因非法数据导致的运行时错误。这篇文章将探讨如何在Java中进行对象属性值的校验,以及相关的工具和源码分析。 首先,对象属性...
在Angular框架中,自定义字段校验指令是扩展表单验证功能的一种有效方式。当内置的验证器无法满足特定需求,例如对IP地址或MAC地址等特殊格式的数据进行验证时,开发者可以创建自己的验证指令。本文将详细讲解如何在...
计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习参考资料计算机技术、IT咨询、人工智能AI理论介绍,学习...
字段校验器直接作用于特定字段,而非字段校验器可以跨多个字段工作。 - 字段校验器配置示例: ```xml 被校验的字段"> 校验器名"> <!-- 校验规则 --> 参数名">参数值 <!-- 错误信息 --> 校验失败后的提示...
字段校验配置直接关联到Action中的属性,而非字段校验配置则需要显式指定被校验的字段名。还可以通过添加`short-circuit="true"`属性实现短路校验,即只显示第一个错误信息。 **二、基于Annotation的输入校验** ...
1、循环校验码(CRC码):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。 2、生成CRC码的基本原理:任意一个由二进制位串组成的代码都可以和一个系数仅为‘0’和‘1’...
字段校验器针对Action类的某个属性进行校验,而非字段校验器则不直接关联具体属性,而是基于某些条件对多个字段进行校验。 #### 字段校验器配置示例: ```xml 被校验的字段"> 校验器名"> 参数名">参数值 ... ...
配置文件内容包括字段校验(field validation)和非字段校验(validator validation)。 - **全局校验配置文件**:全局校验配置文件(如`ActionName-validation.xml`)位于Action类同级目录下,对Action类的所有...
CRC 码是数据通信领域中最常用的差错校验码,其特征是信息字段和校验字段的长度可以任意选定。CRC 码可以检测出数据传输中的错误,从而确保数据的正确性。 二、生成 CRC 码的基本原理 任意一个由二进制位串组成的...
帆软报表填报校验,数据插入时判断插入数据是否和数据库数据是否重复,不重复则插入,重复则显示提示信息“数据插入重复,请检查”,反之则插入成功,报表页面显示插入数据。
统一接口解密封装校验参数测试用例
Spring MVC 是一个强大的Java web应用程序框架,用于构建高效、可维护的Web应用。它整合了Spring框架的功能,提供了模型-视图-控制器(MVC)架构模式,使得开发者可以更专注于业务逻辑,而不是底层实现。...
3. 动态字段校验: 对于动态或者复杂的数据校验需求,Struts2允许在运行时根据不同的请求参数选择不同的校验规则。这可以通过在validate()方法内进行条件判断来实现。 4. 国际化: Struts2支持国际化校验错误消息...