javaweb 自动封装请求头中的数据到指定实体类中

写在开头的话:
这篇笔记是学习web开发时研究反射和泛型的产物,实际开发都是使用spring框架+mybatis 即常说的ssm框架,springMVC已经将servlet封装好了,所以下面的探究过程仅供参考。

引入

在编写向数据库添加数据的方法时,我们需要根据sql的添加语句中需要的"?"去获取request请求中传过来的数据,先用set方法将其封存在对象中,然后再到daoimpl下使用get方法调出数据传给sql语句。根据添加语句的不同,我们就要不断的去改这个过程中使用的set/get方法以及对象的成员变量。

这一切都是重复的,近机械的操作。
因此就生发出“如果java能自动将我请求头中传输的所有数据都存到指定的对象中就好了” 的想法,这样就简化了使用set函数的环节。

实际上是可以实现上面说的想法的,我们只需要编写一个工具类

编写工具类

第一步

既然我们希望能自动将请求中的数据传给我们定义好的对象,而且能实现复用,那么我们就要编写一个工具类用于实现这种操作,这个工具类需要用户传入所有请求参数以及作为容器的class对象,然后传出一个实体对象,这实体对象我们使用泛型表示。
image

第二步

现在我们需要思考如何将map集合中的数据对应到容器中的各个成员变量上:
   首先要明确知道一个前提——请求头中传过来的数据,他们的变量名要与作为容器的对象中的成员变量名相符。
image
在变量名一致的前提下,那么就有两种思路
①map中的key既是请求头中的数据名,又直接对应实体类中成员变量的名字,那么我们就能通过拼接set获得一个set方法
然后将对应key的value数据——string[]的数值以这个set方法存到实体对中对应名字的成员变量中

②使用getDeclaredFields() 获得当前类中所有的成员变量,然后循环使用field对象的set方法

第一种方法算是最底层最原始的方法,我们使用java封装好的方法——即第二种思路

第三步

根据思路写出整个框架:
①首先声明对象用于后面返回
②使用getDeclaredFields()获取指定类中所有的成员变量,返回一个Field数组(注意这个field是一个专门用于java反射的内置的对象,不是我们自定义的对象)
③遍历Field数组,使用getName()获取单个成员变量名
④在传入的储存了所有请求数据的map集合中基于成员变量名获取对应的value——map的k-v为string-string[] 因此返回类型为string[]
⑤非空判断,确定当前循环取到的值不为空时设定暴力破解,然后进行存值
image

第四步

下面详细说明在设定暴力破解后,如何进行存值。
对于请求头中的value,存在多种可能,但是直观表现上可以分为“数组”和“非数组”
①如果此时value的长度大于1,说明取到的值就是一个字符串数组,此时直接使用写好的工具类,将字符串数组拼接成一个字符串,再使用field.set()方法存到对象中

②如果此时value的长度等于1,说明取到的值只是存在字符串数组中,未必就是字符串的值,它可能是下拉框、复选框或者时间的值,此时就需要分别进行类型判断,再用对应类型的变量去存储数据。
相比情况①,情况②需要使用 .getType().getName()获取数据的类型,再进行判断,以确定要使用的数据类型转换工具类,最后再使用field.set()方法存到对象中
image

第五步

外部调用该工具类,只需要传入请求头中所有的请求参数构成的map集合变量以及作为容器的class对象
image
其中步骤②返回给外部时可能是一个对象也可能为空,这是因为工具类中使用了这个方法,这样就便于外部进行非空判定
image

使用到的数据类型转换工具类一览

实际上使用第三方jar包就行了,不需要手动封装这种工具类
image


使用

在写好工具类后,在整个添加数据的流程中,我们只需要:
①根据数据库的表对应着创建对象

②根据sql代码的"?"(需求) 手动使用get方法从对象中取值
(实际上 后面的mybatis+springboots将这个环节也给简化了,配置了对象的成员变量和数据库表的列名的映射后,即可自动实现取值,不过复杂一点的连表查询还是得自己手写sql代码)
说明:这个“sql代码中的?" 指的就是daoImpl中写各种sql语句时的占位符,如图,使用?占位,再使用get方法分别传值。
image

实例:
image

posted @ 2021-08-12 00:28  夏·舍  阅读(637)  评论(0编辑  收藏  举报