网站首页 > java教程 正文
首先关于反射的知识就不说了因为网上的资源实在是太多了,注解的基本知识也不说了,网上同样有很多,好像都是废话,咱们回归正题,今天的内容是通过自定义注解和反射实现参数值的自动验证,那么我们为什么要做这个验证呢?其实我们前端会验证,数据库也会验证,那么我们为什么还要在后台代码中验证呢?个人认为这是一个严谨的问题,首先前端是可以验证,但是如果前端安全验证做的不好,那么你的数据接口会被人分析抓取,当然如果你用的是velocity/jsp/freemaker等一些模板引擎的话是没法抓取接口的,这时候你的接口被抓我就可通过模拟你的接口参数随便提交数据了。这时候有些参数可能不是在接口里携带,这个参数就可以从session中获取,这样可以避免直接访问数据接口被窃取。数据库的话比如建表时如果设置了主外键不为空最大长度类型等,写入数据时数据表也会报错。那么这个算起来的话也算有两次验证了,我们为什么还要在代码里进行验证呢,个人认为第一,还是那句话严谨,要不然这就是bug,哈哈,第二,虽然前端和数据库算是两次验证,但是这样的验证不安全,比如有人写一段注入攻击的js代码提交,第三,这里的验证可以减少数据库的交互压力……
那么问题来了,我们为什么要“手动通过java通过反射和自定义注解实现后台参数值的验证”?,个人原因,第一,为了少写代码,第二,为了能够学习一些知识,第三,就像装会儿逼,当然这也不是多厉害的技术。那么进入正题,以前我们是怎么验证的呢?
1、struts2的valid可以通过配置xml,xml中描述规则和返回的信息,这种方式比较麻烦、开发效率低,不推荐
2、validation bean 是基于JSR-303标准开发出来的,使用注解方式实现,及其方便,但是这只是一个接口,没有具体实现.Hibernate Validator是一个hibernate独立的包,可以直接引用,他实现了validation bean同时有做了扩展,比较强大 ,实现图如下:
点此查看中文官方手册
3、oval 是一个可扩展的Java对象数据验证框架,验证的规则可以通过配置文件、Annotation、POJOs 进行设定。可以使用纯 Java 语言、JavaScript 、Groovy 、BeanShell 等进行规则的编写,本次不过多讲解
4、 Springboot validator实际集成了Hibernatevalidator。主要是校验用户提交的数据的合理性的,比如是否为空了,密码长度是否大于6位,是否是纯数字的,等等。方便后台的数据合法性的校验。
代码基本都长这样
那么一下咱们自己实现一下这个东东
1.第一,创建自定义注解,如下图,咱们先做一个email验证的,其他的基本步骤都一样,举一反三啦
2.第二,编写验证的反射类
/**
* 注解验证方法
*
* @param bean 验证的实体
* @return
*/
@SuppressWarnings("unchecked")
public static Map<String, Object> validate(Object bean) {
Map<String, Object> result = new HashMap<String, Object>();
result.put("message", "验证通过");
result.put("result", true);
Class<?> cls = bean.getClass();
// 检测field是否存在
try {
// 获取实体字段集合
Field[] fields = cls.getDeclaredFields();
for (Field f : fields) {
// 通过反射获取该属性对应的值
f.setAccessible(true);
// 获取字段值
Object value = f.get(bean);
// 获取字段上的注解集合
Annotation[] arrayAno = f.getAnnotations();
for (Annotation annotation : arrayAno) {
// 获取注解类型(注解类的Class)
Class<?> clazz = annotation.annotationType();
// 获取注解类中的方法集合
Method[] methodArray = clazz.getDeclaredMethods();
for (Method method : methodArray) {
// 获取方法名
String methodName = method.getName();
// 过滤错误提示方法的调用
if(methodName.equals("message")) {
continue;
}
// 初始化注解验证的方法处理类 (我的处理方法卸载本类中)
Object obj = ValidateUtil.class.newInstance();
// 获取方法
try {
// 根据方法名获取该方法
Method m = obj.getClass().getDeclaredMethod(methodName, Object.class, Field.class);
// 调用该方法
result = (Map<String, Object>)m.invoke(obj, value, f);
/* 验证结果 有一处失败则退出 */
if(result.get("result").equals(false)) {
result.put(f.getName(), value);
return result;
}
} catch (Exception e) {
e.printStackTrace();
log.info("找不到该方法:"+methodName);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
log.info("验证出错");
}
return result;
}
3.第三我们编写验证方法,这里我用一个正则来实现
4.编写一个实体类,用于验证,这里是测试我们随便写
5.我们直接在main函数中进行测试。
6.输出结果,我传的是手机号,所以验证失败了
那么这个流程就算完了,那么现在这个是最简单的一个验证,完了之后我们还可以扩展很多出来,比如我们要封装一个mvc框架,我们可以在controller层实现参数的接收封装,参数验证如下图
这样就可以实现参数自动接受封装和验证,当然通过注解和反射也可以做其他事情如,路由映射,权限验证,xss攻击过滤,数据处理,实现aop,数据表结构实体映射等等,大家自己动手试试吧
- 上一篇: Java 自定义注解在登录验证的应用
- 下一篇: 「干货」如何将反射和自定义注解应用在项目开发中
猜你喜欢
- 2024-09-27 在Spring Boot项目中创建和使用自定义注解
- 2024-09-27 这一篇 Java 注解,写得太好了(java注解使用)
- 2024-09-27 学习廖雪峰的JAVA教程---注解(定义注解@interface)
- 2024-09-27 自定义注解妙用,一行代码搞定用户操作日志记录,你学会了吗?
- 2024-09-27 Spring Boot 整合mybatis,使用注解的方式(自动生成注解)
- 2024-09-27 面试官:实际工作中哪里用到了自定义注解?
- 2024-09-27 使用自定义注解和切面AOP实现Java程序增强
- 2024-09-27 Java-注解有什么用?该怎么用?(java 注解的作用)
- 2024-09-27 Java 17中的元注解:自定义注解的行为
- 2024-09-27 自定义注解你真会用吗?(说说自定义注解的场景及实现)
你 发表评论:
欢迎- 最近发表
-
- Java常量定义防暴指南:从"杀马特"到"高富帅"的华丽转身
- Java接口设计原则与实践:优雅编程的艺术
- java 包管理、访问修饰符、static/final关键字
- Java工程师的代码规范与最佳实践:优雅代码的艺术
- 编写一个java程序(编写一个Java程序计算并输出1到n的阶乘)
- Mycat的搭建以及配置与启动(mycat部署)
- Weblogic 安装 -“不是有效的 JDK Java 主目录”解决办法
- SpringBoot打包部署解析:jar包的生成和结构
- 《Servlet》第05节:创建第一个Servlet程序(HelloSevlet)
- 你认为最简单的单例模式,东西还挺多
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)