专业的JAVA编程教程与资源

网站首页 > java教程 正文

手动通过,java通过反射和自定义注解实现后台参数值的验证

temp10 2024-09-27 23:02:45 java教程 6 ℃ 0 评论

首先关于反射的知识就不说了因为网上的资源实在是太多了,注解的基本知识也不说了,网上同样有很多,好像都是废话,咱们回归正题,今天的内容是通过自定义注解和反射实现参数值的自动验证,那么我们为什么要做这个验证呢?其实我们前端会验证,数据库也会验证,那么我们为什么还要在后台代码中验证呢?个人认为这是一个严谨的问题,首先前端是可以验证,但是如果前端安全验证做的不好,那么你的数据接口会被人分析抓取,当然如果你用的是velocity/jsp/freemaker等一些模板引擎的话是没法抓取接口的,这时候你的接口被抓我就可通过模拟你的接口参数随便提交数据了。这时候有些参数可能不是在接口里携带,这个参数就可以从session中获取,这样可以避免直接访问数据接口被窃取。数据库的话比如建表时如果设置了主外键不为空最大长度类型等,写入数据时数据表也会报错。那么这个算起来的话也算有两次验证了,我们为什么还要在代码里进行验证呢,个人认为第一,还是那句话严谨,要不然这就是bug,哈哈,第二,虽然前端和数据库算是两次验证,但是这样的验证不安全,比如有人写一段注入攻击的js代码提交,第三,这里的验证可以减少数据库的交互压力……

那么问题来了,我们为什么要“手动通过java通过反射和自定义注解实现后台参数值的验证”?,个人原因,第一,为了少写代码,第二,为了能够学习一些知识,第三,就像装会儿逼,当然这也不是多厉害的技术。那么进入正题,以前我们是怎么验证的呢?

手动通过,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,数据表结构实体映射等等,大家自己动手试试吧

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表