JavaWeb六-书城项目第五阶段------图书模块、图书分页、前台分页、Cookie、Session











jsp/html---view    Book类/JavaBean类 --- Model    Servlet程序类-----Controller
 













再逐一测试

执行删除后,要想让id自增接着按照前面的序号,需要执行sql    ALTER TABLE t_book AUTO_INCREMENT = 1







指定访问的servlet程序及post参数(action判断)


manager.jsp页面跳转
方便权限管理


***** 共性Servlet类中放入post请求(判断action--调用指定方法) *****

无论那个子类继承BaseSerlvet,this就代表该子类---即获取该子类中指定action值的方法


BookServlet程序list()

        



manager.jsp
  

 

列表功能的实现

取出域中的books,遍历,遍历项设为book


前台后台
​​​​​​


 --- 需要参数注入  webutils中的参数为copyParamToBean()
表单提交----book_manager.jsp
地址为后台Servlet程序,提交方式get/post一样(get中调用了psot),隐藏域action=add(设置隐藏域action对应方法名)



需要提交的表单项的name需要对应指定的Book类属性名  ------  不然参数注入出错


编写add方法
 
请求转发会出错,导致F5后多次提交-----------使用重定向     
请求转发为一次请求,重定向为第二次请求,request域中的数据存在一次请求中


请求转发存在的问题,因为请求转发是一次访问多个页面,浏览器会缓存最后访问的信请求息,当按下功能键F5,请求会再次提交,将上次提交的信息全部再提交一次,导致表单重复提交,清理缓存也不行

解决办法:add方法中的请求转发改为重定向,将以此访问变为两次访问,当再次F5,只会进行重定向操作到list查询,不会进行添加

 注意: 请求转发的 / 表示工程名
             重定向的 / 表示端口号,所以利用重定向代替请求转发,需要添加工程名   req.getContextPath()
也可以直接写完整的访问路径
 


删除图书功能实现                                只需要一个id---webutils的字符转Int

提交表单到后台---action=delete,id=图书编号

1. BookServlet中获取请求参数id
2. 调用bookServlet.deleteBookById(),删除图书
3. 重定向跳到图书列表页面


可以直接重定向
 



获取的参数为字符串,删除方法需要的是integer类型,需要转型
     

优化:在WebUtils中编写String---Integer方法

 

添加删除提示功能-----给删除添加点击事件
删除的a标签设置class,通过class来设置点击事件


confirm() 是一个提示框,两个选项,返回true是点了确认,false是点了取消
直接返回confirm的值,true就提交表单,页面跳转,false阻止元素默认行为(阻止表单提交)

提示信息中,穿插获取要删除的行的书名name------this(当前正在执行的dom对象)、parent(父标签)、find("td:first")(标签内查找)

 

修改图书功能实现

-------------------------------------------------------------------------------------------------------------
第一步:回显需要修改的信息给book_edit.jsp
通过jsp页面----> 跳转到jsp页面,无法操作数据库,可以先访问Servlet程序,在请求转发到指定jsp页面



book_manager.jsp中跳转Servlet请求,传入参数(指定方法getBook和需修改的id) 

Web层 getBook方法,通过id(forEach获取的遍历项book)获取参数(指定book),再回写到域中,请求转发到编辑页面

 

---------------------------------------------------------------------------------------------
第二步:提交修改的信息,保存到服务器






存在待解决的问题:
添加、修改都需要使用book_edit.jsp的隐藏域,来判断调用对应方法
book_edit.jsp 的隐藏域已经用来标示add添加操作,还要标示update更新操作


 
--------------每个请求都自带一个method="xxx"参数,给隐藏域获取

在添加图书的a标签中添加参数add,在修改的a标签中添加参数update


在book_edit.jsp隐藏域中${param.method}获取指定的操作参数值add/update,动态获取隐藏域


   



--------------隐藏域判断请求的参数是否存在“id“,来判断add/update

添加操作请求重定向到book_edit.jsp的url      有 id参数
更新修改请求重定向到book_edit.jsp的url      没有id参数

EL表达式param获取请求参数----------通过判断请求参数中是否有id,来判断使用

 


-------------隐藏域判断request域中是否存在book(getBook获取并放进域中的book),来判断add/update

注意:回显时,获取id用的book是list遍历的循环项,没有在域中


编写更新Servlet方法:update()


通过解决book_edit.jsp冲突后,请求到update方法------将参数封装到book,更新book,重定向回列表


存在问题:
获取的参数中不包含 书籍 id ,数据库查询通过id查找不到
book_edti.jsp页面没有获取id,没有传递id参数给Servlet update
 
解决办法:
表单提交时,增加隐藏域id          (或者在修改页面增加id项,参数传递时,全部传入map)


  ---------------------------------------------------------------------------------------------------

 

 




首先创建一个Page<T>类,带泛型,因为不止Book一个模块使用
同理:当前页数据等,都需要使用泛型的集合存放数据


一、分页初步实现

1.  Servlet程序----page()方法
获取请求参数  pageNo   pageSize
用service的page()方法,用pageNo、pageSize参数获取一个封装好的page对象(包含需要的值)
将获取的page对象放入域中
请求转发

第一次访问page, pageNo、pageSize为空,使用默认值


2. service层的------page(pageNo,pageSize)方法
创建page对象
设置当前页、设置每页显示数量、设置总记录数、设置总页码、设置当前页数据
查询总记录数        -----Dao层queryForPageTotalCount()方法查询
计算总页码           ------总记录数 / 每页显示数量
获取当前页数据    ------索引开始位置(begin =(当前页-1)*  每页显示数量),再用Dao层queryForPageItems()方法查询



3. Dao层-----求总记录数 + 求当前页数据方法
select  count(*) from t_book
select * from t_book limit begin,pagesize


4. 分别测试Dao层 
             Service层 

 


5. 实现界面显示分页界面
修改公共的图书管理跳转地址------action=page-----请求访问Servlet的page方法跳转 --- book_manager.jsp

遍历源修改为 域中的page对象的items属性

添加分页导航栏

 

  ----给分页条的确定按钮添加点击事件(location.href)
location.href获取地址栏中的地址
赋值location.href,进行跳转
location必须小写


可以调用base标签的地址,通过写入page域中,再在地址跳转处获取  ---------动态获取请求根地址

 

 

检验搜索页数超出范围
方法一: 在分页条提交按钮处,事件中判断
在按钮处JavaScript中判断pageNo的值超出范围的操作 --不推荐

方法二:在Page类的设置当前页方法中判断-----即要跳转的页面-----超过就设为末页,小于就设为首页
数据边界有效检查

将有效检查设置在page的setpageNo()方法里,所有模块调用分页时,都能使用----提高通用性

 















 


 

<%--<c:choose>
            <c:when test="${requestScope.page.pageTotal<=5}">
                <c:forEach begin="1" end="${requestScope.page.pageTotal}" var="i">
                    <c:if test="${i==requestScope.page.pageNo}">
                        【${i}】
                    </c:if>
                    <c:if test="${i!=requestScope.page.pageNo}">
                        <a href="${requestScope.page.url}&pageNo=${i}">${i}</a>
                    </c:if>
                </c:forEach>
            </c:when>
            <c:when test="${requestScope.page.pageTotal>5}">
                <c:choose>
                    <c:when test="${requestScope.page.pageNo<3}">
                        <c:forEach begin="1" end="5" var="i">
                            <c:if test="${i==requestScope.page.pageNo}">
                                【${i}】
                            </c:if>
                            <c:if test="${i!=requestScope.page.pageNo}">
                                <a href="${requestScope.page.url}&pageNo=${i}">${i}</a>
                            </c:if>
                        </c:forEach>
                    </c:when>
                    <c:when test="${requestScope.page.pageNo>requestScope.page.pageTotal-3}">
                        <c:forEach begin="${requestScope.page.pageTotal-4}" end="${requestScope.page.pageTotal}" var="i">
                            <c:if test="${i==requestScope.page.pageNo}">
                                【${i}】
                            </c:if>
                            <c:if test="${i!=requestScope.page.pageNo}">
                                <a href="${requestScope.page.url}&pageNo=${i}">${i}</a>
                            </c:if>
                        </c:forEach>
                    </c:when>
                    <c:otherwise>
                        <c:forEach begin="${requestScope.page.pageNo-2}" end="${requestScope.page.pageNo+2}" var="i">
                            <c:if test="${i==requestScope.page.pageNo}">
                                【${i}】
                            </c:if>
                            <c:if test="${i!=requestScope.page.pageNo}">
                                <a href="${requestScope.page.url}&pageNo=${i}">${i}</a>
                            </c:if>
                        </c:forEach>
                    </c:otherwise>
                </c:choose>
            </c:when>
        </c:choose>--%>


 

简化:
由于每次只执行一次请求,一次forEach,将forEach独立出来,每个需要调用到forEach的地方,只需设置begin,end的值

 

注意:
分页后,需要将原来跳转到 list 的操作add、delete、update等,重定向为page


分页对增删改操作的影响

add需要传递末页参数  pageTotal
删除、修改需要传递当前页参数  pageNo
 

添加
1. 添加图书跳转处,传递分页-总页数参数pageTotal

2. 获取传递的pageTotal参数---放入隐藏域pageTotal

3. 添加方法add中,获取总页数pageTotal,再加一,保证跳转后肯定是最后一页(传递的12页,新加后变13,冲突)

4. 添加完,重定向地址中,总页数值 pageTotal 传递给 当前页 pageNo------跳转到添加的最后一页处

删除
1. 删除图书跳转处,传递分页-当前页参数pageNo   -------- page对象在跳转page方法时,就存入域中了

2. 重定向地址中,当前页值传递给 pageNo -----删除后跳转到被删除的当前页

修改
1. book_manager.jsp修改图书跳转处,传递分页-当前页参数pageNo   

2. 在book_edit.jsp中,获取传递的pageNo参数---放入隐藏域pageNo

       也可将1的参数名改为pageTotal,利用原有的隐藏域pageTotal传递,update方法中的重定向参数就将pageTotal-->pageNo
3. 重定向地址中,当前页值传递给 pageNo,  再将pageNo返回到显示页面

 

 

创建client下的index.jsp,将web下的index.jsp内容复制----(真正的首页)


一、前台页面跳转
web下的index.jsp-----作为跳转到clientBookServlet的中介-----再跳转到真正的client下的index.jsp
注意:跳转时,访问page
web下的index.jsp


通过page请求转发到client下的index.jsp

     

二、前台分页遍历显示
将图书块进行forEach遍历,遍历源为域中page.items,输出项book,显示每个book的属性
/*单独的一项书籍信息:*/
 


三、分页条抽取

复制 book_manager.jsp  <div id="page_nav">的内容------分页条,将所有跳转地址改为client/bookServlet,进行跳转
 






优化:
          前台的分页条中的页面跳转,的访问Servlet程序及参数
           替换为page的属性url获取
                       -----在page中加入url属性,在page方法中设置url属性


          后台的分页条中的页面跳转,的访问Servlet程序及参数
           替换为page的属性url获取
                       -----在page中加入url属性,在page方法中设置url属性


优点:当需要改页面的跳转地址时,只需修改page.setUrl的url变量值

前台后台不同处为跳转的url不同,将不同的部分设为page对象的url属性,放入域中调用,此时就可以抽取出来该分页条块
跳转部分使用与的page的url代替

二次优化:
       当前台和后台的url都替换成后,分页条部分代码完全一样,就可以将分页条的部分抽取到common中,通过静态包含调用




静态包含调用

 

 

表单
web_index->clientservlet->client_index.jsp请求跳转到前台pageByPrice    传递min、 max参数(在clientBookServlet中设置了)

Servlet程序-----pageByPrice
获取请求参数pageNo、pageSize、min、max
url设置---参数action跳转到pageByPrice---供下一次价格区间查询---传回分页条中需要用到url的地方
                                               实现输入价格区间查询后,再次下一页。。。还是在查询的结果中跳转
                                               但还需要传递min、max参数-------------min、max添加到url后(判断是否存在才添加)

page对象放入域中
重定向到前台


Service层
求总记录、总页码、当前页数据
参考page的方法,传入min、max参数
调用Dao的两个方法  

 

Dao层
参照    方法
传入min、max,在sql中通过price在区间查询
  中传入min、max




测试Dao、Service、Servlet程序


 


 


参数pageByPrice供---在区间查询结果下,再点击下一页等,访问价格区间查询
当输出价格区间的书籍后,点击下一页,出错-----价格参数min、max------------没有给请求传递min、max参数

     

 

 

 

---服务器创建Cookie,保存在客户端的

   ---服务器通知客户端保存键值对的一种技术
     

--------new Cookie(key,value)



注意:resp.addCookie(cookie)必须有,否则客户端不会受到Cookie的创建
 

 -------getCookies()


获取所有Cookie   -------req.getCookies()

查找单个Cookie   --------将所有Cookies遍历,取出单个特定key 的 Cookie

创建查找工具类  ---- 遍历Cookies,找到指定key的Cookie

  

 



一:要改谁,就创建同名的Cookie,构造时传递值,再传回客户端




二:要改谁,就获取该Cookie,通过setValue()改值,再传回客户端


      

 



F12 --- Aplication --- Cookies


F12--- 存储

 





setMaxAge()
       正数 -------  指定秒后删除
       负数 -------  浏览器关闭后 删除
       0      -------  马上关


过期时间设为一小时后





设置cookie的过期时间为过期,浏览器就会马上删除


注意:
1. Servlet程序方法写好后,需要在页面跳转处绑定Servlet方法入口action
2.正常创建的Cookie都是session类型-----------浏览器关就删

 




Path一般为当前工程路径


例如:



       

 

访问路径中增加abc


敲回车---客户端发送过来的Cookie两个都有,因为/工程路径/abc也包含了默认的工程路径

 




登陆成功后才有cookie
回显的用户名,使用的是EL表达式的cookie隐含对象,username表示cookie的Name,value表示cookie的Value




 

 


    ---------维护一个客户端和服务器之间关联的一种技术




 

第一次点击是true---新创建的

后面点击的是false---不是新创建的

 





设置跳转Servlet和参数

在iframe中输出存取的信息


 








            





 


session超时时长的概念:  


当设置了超时时长为3秒后,在期间不停请求( isNew / req.getSession().getAttribute() )
每次请求后,超时时长 timeout 都被刷新, timeout=3

示例代码:



先创建一个session  -----   isNew----true

再次点击创建、获取  -----   isNew----false

设置
3秒后,再次点击创建获取  -----  isNew----true

 


 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值