第十七章 书城项目

发布时间:2024年01月15日

第十七章 书城项目

1.第一阶段 表单验证的说明

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.第一阶段:表单验证的实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上面是静态页面
下面进行我们的操作
下面是用户名的验证
在这里插入图片描述
在这里插入图片描述
下面是密码的验证
在这里插入图片描述
确认密码
在这里插入图片描述
邮箱验证
在这里插入图片描述
在这里插入图片描述
为了防止有人在验证码中输入一堆空格
在这里插入图片描述
在这里插入图片描述

3.第二阶段:用户登录和注册功能的介绍

在这里插入图片描述
下面我们要将在客户端(浏览器)中输入的用户名,密码等信息发送给服务器,
并且将其保存到数据库的

在这里插入图片描述
上面的登录信息也一样,我们同样发送给服务器,服务器获取用户名和密码,
并到数据库进行检查,正确则登入成功。

4.JavaEE三层架构介绍

在这里插入图片描述

5.搭建书城项目环境

在这里插入图片描述
在这里插入图片描述

6.创建数据库和t_user用户表

在这里插入图片描述
在这里插入图片描述

7.创建数据库表对应的user类

在这里插入图片描述

8.JdbcUtils工具类的编写与测试

在这里插入图片描述
下面我们在WEB-INF中新建lib,放入Druid(德鲁伊)和mysql驱动

在这里插入图片描述
下面我们添加jar包
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一个librarys类似于一个分组效果,一个组里面可以有多个jar,我现在将某个组挂在某个module下面,就将组里面所有的jar挂在了这个module下面
我们其实也可以右击直接添加到项目中(直接右键单击jar包,add as library即可),上面这样是为了方便管理

我们再将book_lib这个jar包添加到book这个module下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

jar包前出现了 > 的标记
在这里插入图片描述

使用druid需要下面的配置文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面对其进行测试
记得每次用完都要关闭数据库,释放资源
在这里插入图片描述
其中新加入的两个jar是用来,运行@Test的
在这里插入图片描述
在这里插入图片描述

9.编写baseDao

要使用DbUtils操作数据库,要先导入包
这里直接将这个包加入book_lib中就行了,不需要后续的操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面是查询返回一个对象
在这里插入图片描述
记得关闭连接
在这里插入图片描述
在这里插入图片描述

下面为查询返回多个对象
在这里插入图片描述
下面为查询某一列某一行的情况
在这里插入图片描述

10.编写UserDao和测试

下面我们要编写具体的Dao,BaseDao是为了让UersDao继承才写出来的
我们先写接口
在这里插入图片描述
在这里插入图片描述

下面为接口的实现体
在这里插入图片描述

在这里插入图片描述

下面我们测试一下
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
返回-1表示插入失败,1表示插入成功

11.编写UserService和测试

Service是业务层,比如登入和注册都是service
我们先写接口
在这里插入图片描述
下面写实现体
下面的三个操作我们都要去操作数据库
在这里插入图片描述
下面我们new一个数据库对象进行操作
在这里插入图片描述
在这里插入图片描述
下面我们依旧进行一下测试
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

12.实现用户注册功能

在这里插入图片描述
配置
在这里插入图片描述

Regist.html就是注册页面
下面是它的form表单,表单的提交对象是registServlet
在这里插入图片描述
这里表单的提交对象只要写registServlet就可以
因为前面已经有了base标签,如果没有base,写绝对路径
在这里插入图片描述
在这里插入图片描述
下面我们进行写服务器代码
在这里插入图片描述
在这里插入图片描述

验证码错误的话,跳回注册页面
在这里插入图片描述
我们由下图知道,web层只能调用service,是不能直接操作Dao
在这里插入图片描述
所以我们要在其中准备一个userService
在这里插入图片描述
在这里插入图片描述

13.idea工具Debug的使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

14.用户登入功能的实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

15.修改所有html页面为jsp页面

在这里插入图片描述

在html页面上面填下面这句话,并且将文件的html后缀改为jsp即可
在这里插入图片描述

其中的一些页面调转可能还含有html后缀,我们可以批量的查找替换
我们点击ctrl+R,这个就是查找替换
在这里插入图片描述

我们也可以点击ctrl + shift + R
*.jsp表示以jsp为后缀的文件
Directory表示按照目录进行搜索
Module表示按照模块进行搜索
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
右下角的replace all表示替换全部

16.抽取所有jsp页面中的公共内容

新建common文件夹存放所有相同的内容
将其中 登入成功 的内容提取出来单独放一个jsp文件中
在这里插入图片描述

在其他jsp文件中直接引用这部分
比如将下面的部分进行替换
在这里插入图片描述
在这里插入图片描述
其他的也进行替换
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面同样的,我们将一些头部信息提取出来,单独放一个jsp文件中
(要将所有页面全部替换掉,下面没有截图)
在这里插入图片描述
在这里插入图片描述
最后我们再将页脚部分全部提取出来
同样要将所有页脚全部替换
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面我们将文本中相同的内容继续提取出来
同样将所有jsp页面中的内容全部替换
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

17.动态的base标签

在这里插入图片描述
在这里插入图片描述
假如我登入的时候是用具体的ip地址时,我们发现登入book时是服务器的ip地址
但在其他界面就是localhost(本机)。
这里如果是我自己访问页面,就没有任何问题,但是其他人访问,这个localhost是到你的电脑上面去访问的
出现这个的原因是我们的base标签定死了路径
所以这里的ip地址,工程路径我们都有必要动态获取
在这里插入图片描述
下面我们就动态的得道完整的路径
在这里插入图片描述
我们将其替换即可

在这里插入图片描述

18.表单提交失败的错误回显

在这里插入图片描述
在这里插入图片描述
在登录或者注册的时候,如果发生错误,应该给用户一些提示,
告知用户是密码错误还是用户名错误
并且之前的输入的用户名密码等信息还要留在表单框内
在这里插入图片描述
下面在输入错误的用户名或者密码时的情况
在这里插入图片描述
在这里插入图片描述
下面实践一下,随机输入一个错误的用户名或者密码
在这里插入图片描述
在这里插入图片描述
下面我们进行用户名和密码的回显操作,表单框中的值是由value决定的
在这里插入图片描述
这里我们假如由于验证码错误,注册失败
在这里插入图片描述
另一种注册错误是用户名已经存在
在这里插入图片描述

以上两种错误我们都回显了错误原因,并且回显了错误信息,
以及回显了填写的用户名和密码信息
下面在页面中进行修改
在这里插入图片描述

在这里插入图片描述

19.代码优化一,合并LoginServlet和RegistServlet程序为UserServlet程序

LoginServlet和RegistServlet都是用户模块的功能,我们将其合并为一个userServlet,
这样的话,一个UserServlet就可以处理两个功能
在这里插入图片描述
在这里插入图片描述
下面在登入注册的页面中添加隐藏域
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们将userServlet地址放到登入注册里面
在这里插入图片描述
在这里插入图片描述
我们在userServlet中写两个功能login和regist,
将loginServlet和registServlet的代码复制粘贴到其中
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

20.代码优化二,使用反射优化大量else if代码

在这里插入图片描述
我们上面每添加一个功能,旁边就要用else if做一个判断
这样我们每次都要修改dopost中的代码,要是有种方法可以一次性写好,不管调用什么功能,右边就能调用相应的功能,我们可以通过反射实现
下面我们先模拟一下
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
到这里我们已经得到了方法,下面我们要进行方法的调用
在这里插入图片描述
在这里插入图片描述

下面我们在进行实际代码的优化
这里我们的实际代码中有参数req和resp,所以action后面要跟两个参数
在这里插入图片描述
Invoke后面:
this是对象实例
req是第一个对象参数
resp是第二个对象参数

21.代码优化三,抽取BaseServlet程序

在这里插入图片描述
由BaseServlet去继承HttpServlet,
而其他的模块,比如UserServlet模块继承BaseServlet即可
在这里插入图片描述
在这里插入图片描述

22.BeanUtils工具类的使用

在这里插入图片描述

如下所示,我们在登入注册中都要将请求参数封装成一个User对象
在这里插入图片描述

此项目中的参数比较少,
但实际开发中,我们可能有十几个参数
我们不仅需要获取参数,还要new对象,调用set方法等
非常麻烦
在这里插入图片描述
BeanUtils类可以解决这个问题
在这里插入图片描述
下面演示一下如何使用(上面的get方法全不用)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以将上面的方法封装到一个JavaBean中
在这里插入图片描述
在这里插入图片描述
下面我们来看一下他的原理
在这里插入图片描述
在这里插入图片描述
当我们改了set方法后,这个值无发注入
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这就是为什么我们改了set方法后,无法注入
下面还有一个点需要注意,我们将HttpServlet改为Map
在这里插入图片描述
下面主要讲req改为req.getParameterMap()即可
在这里插入图片描述

上面修改之后,功能没有任何的影响
那么我们为什么要这样改呢
我们项目还有Dao层和Service层,而这两个是没有HttpServletRequest的
在这里插入图片描述
我们下面还可以再做简化
在这里插入图片描述

下面代码就变成了一行,但我需要一个类型转换
在这里插入图片描述

我们可以直接使用泛型
在这里插入图片描述
这样写就不用类型转换了
在这里插入图片描述

23.使用EL表达式实现表单错误回显

在这里插入图片描述
EL输出空值的时候就是空串,我们可以省去判断

在这里插入图片描述
在这里插入图片描述

24.第五阶段:内容介绍

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

25.MVC概念的介绍

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

26.创建图书模块的数据库表

img_path表达存储的图片的路径
在这里插入图片描述
在其中存储一些用来测试的数据

在这里插入图片描述

27.编写图书模块的JavaBean类Book

在这里插入图片描述
img_path中放的为图书的默认地址
在这里插入图片描述
在这里插入图片描述

28.编写图书模块的Dao和测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下面为测试
我们在接口处点击快捷键ctrl + shift + t
在这里插入图片描述
Destination package是测试的地址
下面勾上5个要测试的方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

29.编写图书模块的Service和测试

在这里插入图片描述

实现接口
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

30.图书列表功能的实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们访问的时候是Get请求,而方法只有doPost
我们可以在doGet方法中调用doPost方法,这样他们做的工作就是一样的了
在这里插入图片描述
在这里插入图片描述

31.前后台的简单介绍

在这里插入图片描述

32.添加图书功能实现

在这里插入图片描述
首先其中要添加隐藏域,告诉系统要调用哪个方法
在这里插入图片描述
这里的name中的属性值要和Book类中的属性值一致,这样才能使用BeanUtils中注入
在这里插入图片描述
在这里插入图片描述
下面是实际的代码
bookServlet?action=List是指请求转发到bookServlet并且调用List方法
在这里插入图片描述
List方法是生成图书页面的
这里就是重新生成一下页面,将新增的图书添加其中
在这里插入图片描述
在这里插入图片描述
上面我们发现时间简史已经添加完成
但有一个bug,就是我们在这个页面点击F5刷新的时候,又一个时间简史会生成
这个bug就是表单重复提交
在这里插入图片描述

所以这里我们不应该使用请求转发,请求转发是一次请求。
应该使用重定向,重定向是两次请求。

这里注意,请求转发的 / 是到工程名
重定向的 / 是到端口号,所以前面要加上工程名
在这里插入图片描述

33.删除图书功能的实现

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这里的将字符串转化为int会用到很多次,
我们将其做成一个方法,放到webUtils中,以便随时调用
defaultValue是一个默认值,当我们转换失败的时候就返回这个默认值,
我们这里将默认值设置为0
在这里插入图片描述
上面写错了
在这里插入图片描述
在这里插入图片描述
我们有时候会不小心点到删除,所以我们在删除的时候,需要提示一些内容
下面我们给删除提供一个单机事件
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
this是当前正在响应的dom对象,我们要找到他父元素的父元素里面的第一个文本内容
在这里插入图片描述
在这里插入图片描述

34.修改图书第一步,回显修改的信息

下面我点击一个修改
在这里插入图片描述
下面应该显示我刚刚点击那一条记录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

最后到book_edit.jsp页面中输出信息(下面是直接用EL输出的,我自己写的个人基因组存储系统是用jsp输出的)
在这里插入图片描述

35.修改图书第二步,提交给服务器保存修改

在这里插入图片描述
我们的添加和修改都是在下面这个book_edit.jsp的页面中实现的
在这里插入图片描述
而我们的book_edit.jsp中已经有了一个隐藏域add
先在还需要一个update
在这里插入图片描述
在这里插入图片描述
实现方案一:
在这里插入图片描述

在这里插入图片描述
下面我们点击添加图书
在这里插入图片描述

页面上面就有一个参数add
在这里插入图片描述

我们代码中的value就通过${param.method}得到这个参数
在这里插入图片描述
当我们在页面点击修改的时候
在这里插入图片描述
代码变为
在这里插入图片描述
解决方案二:
当我点击添加的时候,上面没有参数
在这里插入图片描述
当我点击修改的时候,上面有参数id
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们将其放到value中
在这里插入图片描述
解决方案三:

我们在添加时,直接进去book_edit页面
在这里插入图片描述
在这里插入图片描述
我们在修改操作时,会经过bookServlet(查询有没有这个图书)
在这里插入图片描述
在这里插入图片描述
如果request域中有一个图书对象的话,就是修改
没有的话,就是添加
在这里插入图片描述

这里我们就采用方案二
在这里插入图片描述
在这里插入图片描述
这里操作会失败,因为我们这边修改需要根据id,而我们上面没有上传id
在这里插入图片描述
我们再添加一个隐藏域,用来获取id
在这里插入图片描述

36.图书分页的分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

37.分页模型Page对象的创建

在这里插入图片描述
在这里插入图片描述

38.分页初步实现

在我进入这个页面的时候,就是点击图书管理的时候,我就应该请求这个分页方法page了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面是web层的代码
在这里插入图片描述
下面是service层的代码
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面是Dao的代码
在这里插入图片描述
在这里插入图片描述
最后我们在jsp页面进行遍历,之前是遍历books,现在是遍历page中的items
在这里插入图片描述
在这里插入图片描述
下面就是展示出了第一页的数据
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

39.首页,上一页,下一页,末页的实现

在这里插入图片描述
这里还有个问题,就是我们在首页和尾页的时候,再点击上一页和下一页就没有意义了
我们在首页和尾页的时候,让上一页和下一页隐藏起来
在这里插入图片描述
在这里插入图片描述

40.调到指定页码功能的实现

在这里插入图片描述
输入3,要调到第三页
我们先给按钮绑上单击事件(这里jQuery单机事件直接写在了body体中,似乎也是可以的)

在这里插入图片描述
在这里插入图片描述
比如这里填写的是百度的地址

在这里插入图片描述
点击确定后,直接跳转到百度
这里我们将上面的地址,复制粘贴到其中,页面变为当前页码即可
在这里插入图片描述
在这里插入图片描述
这里还有一个小问题,当我跳转到第5页的时候
虽然页面跳转了过去,但是输入框中的内容还是显示的4
在这里插入图片描述
下面我们做一个修改
在这里插入图片描述

41.数据有效边境检查

这里还有一个问题,下面的ip地址是localhost,其他人访问的时候会出现问题
在这里插入图片描述
下面我们修改一下
在这里插入图片描述
在这里插入图片描述
假如我们输入50(超过了最大页数),或者一些负数
在这里插入图片描述
下面我们调整一下
我们在单机事件中加入if判断(这里没有写)

在这里插入图片描述
下面提示了一下,下面给出了总页码
我们输入的值,不能>1,也不能<总页码

在这里插入图片描述
很多老程序员,可以越过我们的前端jsp页面,直接在网页栏输入pageNo=50
在这里插入图片描述

但这个一定会经过服务器,我们可以在服务器做一个校验,
思路:如果下面这个Pageno值 < 1,我们就将其设置为1
如果 > 最大值,我们就将其设置为最大值

在这里插入图片描述
我们在bookService的page方法中去实现这个思路

在这里插入图片描述
这个代码从功能角度来说已经实现了
但从合理范围,或者优雅的角度来说不行,这个有效边境检查,每个模块只要有分页,我们都要做,我们可以将其放到下面的部分中

在这里插入图片描述
在这里插入图片描述

42.分页条页码的输出

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们下面可以进行一下优化,其中有部分是一模一样的,只是begin和end不同

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上面的代码就是判断一下begin,end的值
判断完之后,在执行最后的这个代码
在这里插入图片描述

43.修改分页对原来添加,删除,修改的影响

在这里插入图片描述
添加完后没有数据,添加完后,它重新跳到了列表管理的list页面
在这里插入图片描述
分页做完之后,我们要将但凡跳转到list页面的,全部转化到page
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
添加提交后,跳转到了第一页,第一页并没有看见我们最后提交的记录
在这里插入图片描述
在这里插入图片描述
这种情况我们可以在跳转的时候,将最后一页的页码发过去,让其跳转到最后一页
在这里插入图片描述
改为
在这里插入图片描述
然后这个最后一页来到这个book_edit这边
在这里插入图片描述
我们现在添加图书,最后一页为11, 11就进入隐藏域中,服务器就会知道一共有11页,
跳到最后一页
在这里插入图片描述
我们重定向的时候也要加上这个页数,以便直接跳转过去

在这里插入图片描述
我们现在再添加数据
在这里插入图片描述
确实是跳到当时的最后一页11页了,但此时还是没有看见添加的记录,因为此时一共有12页了
在这里插入图片描述
在这里插入图片描述

下面有个简单的方法,直接加1即可(不用担心有空位,之前做了校验,
超出最大页数,直接转到最后一页)

在这里插入图片描述

下面我们进行删除的调整,
删除同样要将当前页面发过去,然后转到当前页码看删除的记录还在不在
在这里插入图片描述
修改
同样将当前页码发过去,以便跳转到当前的修改页面,进行查看

在这里插入图片描述
在这里插入图片描述

44.前台分页的初步实现

在这里插入图片描述
上面的网址只写到了工程路径,所以会默认访问index.jsp页面
在这里插入图片描述
在这里插入图片描述
ClientBookServlet中也有一个page分页方法
在这里插入图片描述
他的请求地址换一下
在这里插入图片描述
配置一下
在这里插入图片描述

将原来的index.jsp的内容复制过来
在这里插入图片描述
原来的index.jsp只负责请求转发一件事
在这里插入图片描述
下面我们写index.jsp的内容
循环遍历page的内容
在这里插入图片描述
在这里插入图片描述
下面看一下,只有两条信息
两条是因为前面做分页的时候设置PAGE_SIZE的大小为2
在这里插入图片描述
下面的分页条从之前做的复制粘贴过去即可

在这里插入图片描述
但是其中的地址要变一下,manger变为client
Ctrl + shift + r 或者ctrl + r
在这里插入图片描述

45.分页条的抽取

前台和后台的分页部分,除了前面的地址不同,其他部分全部一样
我们可以将地址抽取出来
在这里插入图片描述
我们将client/bookServlet?action=page替换为 ${requestScope.page.url}
在这里插入图片描述
在这里插入图片描述
除了首页这个,后台也需要替换
在这里插入图片描述
下面我们再进行其它的设置(下面是后台)
在这里插入图片描述
下面是前台
在这里插入图片描述

改完之后有个好处,后面改地址更加方便
前后台分页操作完全一样
我们可以将分页代码提取出来了
在这里插入图片描述
在这里插入图片描述
然后再调用
前台
在这里插入图片描述
后台
在这里插入图片描述

46.价格区间搜索并分页功能的分析

在这里插入图片描述
比如这里我们查出价格10-50全部的图书,并且做一个分页的处理
在这里插入图片描述

48.价格区间搜索并分页功能的实现

在这里插入图片描述
Integer.MAX_VALUE是一个特别大的默认值(包含数据库里面图书的最大价格)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面实现这个接口方法
在这里插入图片描述
在这里插入图片描述
下面是数据库的接口方法
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里看起来很乱,我们进行一个排序
在这里插入图片描述
在这里插入图片描述
下面是@Test得到的结果,我们截屏Test

49.搜索价格区间的回显

在这里插入图片描述

50.解决分页条中不带价格区间的bug

在这里插入图片描述
当我点击下一页的时候,上面的价格区间就不见了
而且我们的页数还变多了
在这里插入图片描述
我们可以看见下面的请求地址中,没有带上面的价格区间

这表示我们在设置下面的url的地址的时候,要带上价格区间
在这里插入图片描述
在这里插入图片描述

文章来源:https://blog.csdn.net/m0_72232218/article/details/135572145
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。