Java进阶学习第二十天——分页与Listener

文档版本 开发工具 测试平台 工程名字 日期 作者 备注
V1.0 2016.05.18 lutianfei none

customer练习(续)

1.添加

  • 问题:id是varchar类型,它的获取问题?

    • UUID工具类来获取.
  • 完成添加操作:
    • 1.在showCustomer.jsp页面上添加一个连接,可以直接访问到添加页面 add.jsp
    • 2.创建add.jsp
      • 1.关于生日的日历组件My97DataPicker

        • 1.导入js,将My97DataPicker文件夹复制到项目根目录WebRoot

          • <script language="javascript" type="text/javascript" src="${pageContext.request.contextPath}/My97DatePicker/WdatePicker.js"></script>
        • 2.在input type=text组件上添加 class,onclick.
          • 客户生日:<input type="text" name="birthday" class="Wdate" onclick="WdatePicker()" readonly="readonly"><br>
        • 3.修改WdataPicker.js文件,改变初始显示时间。
          • startData后面按照格式填入初始时间
      • 2.关于id问题
        • 使用UUID获取
    • 3.创建CustomerAddServlet完成添加操作
      • 1.得到所有请求参数封装到Customer对象

        • 注意:1.编码问题

          • 2.我们使用BeanUtils,注意Date类型转换问题
          • 3.要手动封装id.
      • 2.调用service完成添加操作

2.批量删除

  • 1.完成页面上全选 与全不选操作
    function change(){
        //1.得到id为main的这个checkbox
        var main=document.getElementById("main");

        var flag=main.checked;

        //2.得到所有name=ck的checkbox
        var cks=document.getElementsByName("ck");

        //3.将cks中所有的checkbox的checked值设置为flag
        for(var i=0;i<cks.length;i++){
            cks[i].checked=flag;
        }
    }
  • 2.完成批量删除

    • 1.页面上怎样将数据提交到服务器端

      • 1.可以创建一个表单,将表单数据提交就可以。
      • 2.直接使用js操作
        • 需要手动拼接出url路径
    • 2.在服务器端怎样批量删除
      • 1.得到所有要删除的id值

        • request.getParameterValues(“ck”);
      • 2.在dao中使用QueryRunner的batch方法
        • batch(sql,Object[][]);
        • 注意:参数二维数据,它代表的是每一条sql的参数。
          • {1,2,3}—–>{{1},{2},{3}}
  • <a href="javascript:void(0)" onclick="sendDel();">
    • 这句话的意思是让href选中的连接失效并跳转到javascript中的sendDel()函数。

3.简单条件查询

  • 1 . 在showCustomer.jsp页面上完成
    <div align="center">
        <form>
        <select name="s">
            <option>请选择条件</option>
            <option value="name">按姓名查询</option>
            <option value="cellphone">按手机号查询</option>
            <option value="description">按描述查询</option>
        </select>
        <input type="text" name="msg">
        <input type="submit" value="查询">
        </form>
    </div>
  • 问题: select的名称叫什么?每一个option的值是什么?

    • select可以任意起名。
    • option的value名称需要与customer表中的字段名称对应。
  • 2 . 创建CustomerSimpleSelectServlet完成条件查询
    • 注意sql语句问题:

      • String sql="select * from customer where "+field+" like ?";
      • 一旦使用就相当于加了单引号‘’

分页查询

  • 分页就是将数据以多页去展示,使用分页可以提高客户的感受。

分页分类

  • 1.物理分页

    • 只从数据库中查询出当前页的数据。
    • 优点:不占用很多内存
    • 缺点:效率比较低
  • 2.逻辑分页
    • 从数据库中将所有记录查询出业,存储到内存中,要想展示当前页数据,直接从内存中获取。
    • 优点:效率高
    • 缺点:占用内存比较高
  • 在java开发领域,我们使用的比较多的是物理分页
物理分页的实现
  • 1.直接使用jdbc完成

    • 使用滚动结果集。

      • 优点:跨数据库。
      • 缺点:性能低。
  • 2.使用数据库本身提供的分页操作.
    • 会使用每一个数据库特定的分页函数

      • 优点:性能高
      • 缺点:不能跨数据库。
      • 分页命令关键字:
        • mysql:limit
        • sqlservlet:top
        • oracle:rownum
mysql中使用limit进行分页
  • select * from 表 limit m,n;

    • m:代表的是从第几条开始 注意:它是从0开始记录.
    • n:代表查询几条记录.
  • 示例:分页池,每页显示6条,要查询第2页的数据
    • select * from 表 limit (页码-1)*每页条数,每页条数;

分页分析及代码实现

  • 1.页码 : 默认第一页
  • 2.每页条数 : 人为定义
  • 3.总条数 : select count(*) from 表
  • 4.总页数 : 总页数=Math.ceil(总条数*1.0/每页条数);
  • 5.当前页的数据 select * from 表 limit (页码-1)*每页条数,每页条数;
分页代码实现
  • 1.在success.jsp页面上

    • <a href="${pageContext.request.contextPath}/findAllByPage">查看所有客户信息(分页展示)</a><br>
  • 2.创建CustomerFindAllByPageServlet完成分页
    • 问题:要向页面携带的数据有很多,不仅是要展示的数据,例如:页码,总页数等,都需要携带到页面上,怎样处理?

      • 解决方案:可以创建一个分页Bean,在这个Bean中封装所有关于分页相关的数据.
    private int pageNum; // 页码
    private int currentPage; // 每页条数
    private int totalPage; // 总页数
    private int totalCount; // 总条数
    private List<Customer> cs; // 每页数据
  • 3.在showCustomerByPage.jsp页面上添加
    <a href="/day20_1/findAllByPage?pageNum=1">首页</a>&nbsp;&nbsp;&nbsp;
    <a href="/day20_1/findAllByPage?pageNum=${pb.pageNum-1}">上一页</a>&nbsp;&nbsp;&nbsp;
    <a href="/day20_1/findAllByPage?pageNum=${pb.pageNum+1 }">下一页</a>&nbsp;&nbsp;&nbsp;
    <a href="/day20_1/findAllByPage?pageNum=${pb.totalPage }">尾页</a>&nbsp;&nbsp;&nbsp;
* 在CustomerFindAllByPageServlet中处理请求参数 pageNum
        int pageNum = 1;
        String _pageNum = request.getParameter("pageNum");
        if (_pageNum != null) {
            pageNum = Integer.parseInt(_pageNum);
        }
  • 问题:怎样控制上一页,下一页。
    条件判断就可以解决.
    <c:if test="${pb.pageNum==1}">
        上一页&nbsp;&nbsp;&nbsp;
    </c:if>
    <c:if test="${pb.pageNum!=1}">
        <a href="/day20_1/findAllByPage?pageNum=${pb.pageNum-1}">上一页</a>&nbsp;&nbsp;&nbsp;
    </c:if>

    <c:if test="${pb.pageNum==pb.totalPage}">
        下一页&nbsp;&nbsp;&nbsp;
    </c:if>
    <c:if test="${pb.pageNum!=pb.totalPage}">
        <a href="/day20_1/findAllByPage?pageNum=${pb.pageNum+1 }">下一页</a>&nbsp;&nbsp;&nbsp;
    </c:if>

分页扩展

  • 1.设定每页显示条数

    • 1.在showCustomerByPage.jsp页面上添加一个<select>
    <select name="currentPage" onchange="changeCurrentPage(this.value);">
        <option>--请选择每页条数--</option>
        <option value="5">5</option>
        <option value="10">10</option>
        <option value="20">20</option>
    </select>

    function changeCurrentPage(value){
        location.href="/day20_1/findAllByPage?currentPage="+value;
};    
* 2.在首页,上一页,下一页,尾页的连接上也要添加每页显示条数。
    * `<a href="/day20_1/findAllByPage?pageNum=1&currentPage=${pb.currentPage}">首页</a>`
  • 2.关于页码显示
    <c:forEach begin="1" end="${pb.totalPage}" var="n" step="1">
        <a href="/day20_1/findAllByPage?pageNum=${n}&currentPage=${pb.currentPage}">第${n}页</a>&nbsp;&nbsp;
    </c:forEach>
  • 问题:如果页码比较多怎样处理?

    • 可以限定页码数,例如:前5后4。
    • 这样做,页面的判断条件比较多,可以使用自定义标签。
    • 可以在自定义标签中通过java代码来解决判断操作。如果直接在页面上,使用<c:if>代码太乱。

监听器

  • 监听事件的发生需要如下因素:

    • 1.事件 ActionEvent
    • 2.事件源 JButton
    • 3.监听器 ActionListener
    • 4.注册监听 addActionListener();
  • 监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
  • 在javaweb中有什么监听器,有什么作用?
    • javaweb中的监听器,主要用于监听javaweb中常用对象

      • request(HttpServletRequest)
      • session(HttpSession)
      • application(ServletContext)
    • 监听器的作用
      • 1.对象的创建与销毁
      • 2.对象的属性变化
      • 3.session绑定javaBean.
  • 1.监听创建与销毁

    • HttpServletRequest

      • 监听器:ServletRequestListener可以监听request对象的创建销毁
    • HttpSession
      • 监听器:HttpSessionListener可以监听session对象的创建销毁
    • ServletContext
      • 监听器:ServletContextListener可以监听application对象的创建销毁
  • 2.监听web对象的属性变化
    • HttpServletRequest属性变化

      • 监听器:ServletRequestAttributeListener监听request对象的属性变化
    • HttpSession属性变化
      • 监听器:HttpSessionAttributeListener 监听session对象的属性变化
    • ServletContext属性变化
      • 监听器:ServletContextAttributeListener监听application对象的属性变化。

编写监听器

  • 和编写其它事件监听器一样,编写servlet监听器也需要实现一个特定的接口,并针对相应动作覆盖接口中的相应方法。
  • 和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由WEB容器负责注册,开发人员只需在web.xml文件中使用<listener>标签配置好监听器,web容器就会自动把监听器注册到事件源中。
  • 一个 web.xml 文件中可以配置多个 Servlet 事件监听器,web 服务器按照它们在 web.xml 文件中的注册顺序来加载和注册这些 Serlvet 事件监听器。
创建监听器步骤
  • 1.创建一个类,去实现指定的监听器接口.
  • 2.重写接口中方法。
  • 3.在web.xml文件中配置注册监听
    <!-- 监听器案例-->
    <listener>
        <listener-class>cn.itcast.listener.demo.MyServletContextListener</listener-class>
    </listener>
  • 具体实现
  • 1.监听application对象的创建与销毁.
    • 问题:application对象什么时候创建,什么时候销毁的?

      • application对象是服务器启动时创建,服务器关闭时销毁。
  • 2.监听session对象创建与销毁
    • 问题:session对象什么时候创建,什么时候销毁?

      • session对象创建:

        • reqeust.getSession();它是用于获取session

          • 是否创建,分以下几种情况:

            • 1.请求中如果没有jsessionid,那么就是创建session对象。
            • 2.如果请求头中有jsessionid值:
              • 1.如果在服务器端,有一个session的id值与其一样,不创建,直接使用。
              • 2.如果在服务器端,没有这个session的id值,那么会创建。
      • session对象销毁:
        • 1.默认超时 30 分钟
        • 2.设置session超时时间
          • setMaxInactiveInterval(int interval)
        • 3.invalidate()手动销毁
        • 4.关闭服务器
  • 3.监听request对象创建与销毁

    • 问题:request对象什么时候创建,什么时候销毁?

      • 请求发生,request对象创建,响应产生request对象销毁。

ServletContext监听器

  • ServletContextListener 接口用于监听 ServletContext 对象的创建和销毁事件。
  • 当 ServletContext 对象被创建时,激发contextInitialized (ServletContextEvent sce)方法
  • 当 ServletContext 对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。
  • 提问,servletContext域对象何时创建和销毁:
    • 创建:服务器启动针对每一个web应用创建servletcontext
    • 销毁:服务器关闭前先关闭代表每一个web应用的servletContext
  • 示例1 简单任务调度Timer与TimerTask使用

Servlet监听器

  • 在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为 ServletContext, HttpSessionServletRequest 这三个域对象。
  • Servlet规范针对这三个对象上的操作,又把这多种类型的监听器划分为三种类型。
    • 监听三个域对象创建销毁的事件监听器
    • 监听域对象中属性增加和删除的事件监听器
    • 监听绑定到 HttpSession 域中的某个对象的状态的事件监听器。(查看API文档)
  • 在javaweb中servlet规范中定义了三种技术 : servlet Listener Filter

HttpSession监听器

  • HttpSessionListener接口用于监听HttpSession的创建销毁

    • 创建一个Session时,sessionCreated(HttpSessionEvent se) 方法将会被调用。
    • 销毁一个Session时,sessionDestroyed (HttpSessionEvent se) 方法将会被调用。

ServletRequest监听器

  • ServletRequestListener 接口用于监听ServletRequest 对象的创建和销毁。

    • Request 对象被创建时,监听器的requestInitialized方法将会被调用。
    • Request对象被销毁时,监听器的requestDestroyed方法将会被调用。
  • 当向被监听器对象中增加一个属性时,web容器就调用事件监听器的 attributeAdded 方法进行相应,这个方法接受一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象。
    • 各个域属性监听器中的完整语法定义为:

      • public void attributeAdded(ServletContextAttributeEvent scae)
      • public void attributeAdded (HttpSessionBindingEvent hsbe)
      • public void attributeAdded(ServletRequestAttributeEvent srae)

监听三个域的属性变化

  • Servlet规范定义了监听 ServletContext, HttpSession, HttpServletRequest 这三个对象中的属性变更信息事件的监听器。
  • 这三个监听器接口分别是ServletContextAttributeListener, HttpSessionAttributeListener ServletRequestAttributeListener
  • 这三个接口中都定义了三个方法来处理被监听对象中的属性的增加删除替换的事件,同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同。
  • 当向被监听器对象中增加一个属性时,web容器就调用事件监听器的 attributeAdded 方法进行相应,这个方法接受一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象
  • 各个域属性监听器中的完整语法定义为:
    • public void attributeAdded(ServletContextAttributeEvent scae)
    • public void attributeAdded (HttpSessionBindingEvent hsbe)
    • public void attributeAdded(ServletRequestAttributeEvent srae)
  • 当**删除被监听对象中的一个属性时,web 容器调用事件监听器的这个方法进行相应
  • 各个**域属性监听器中的完整语法定义为:
    • public void attributeRemoved(ServletContextAttributeEvent scae)
    • public void attributeRemoved (HttpSessionBindingEvent hsbe)
    • public void attributeRemoved (ServletRequestAttributeEvent srae)
  • 当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的这个方法进行相应
  • 各个域属性监听器中的完整语法定义为:
    • public void attributeReplaced(ServletContextAttributeEvent scae)
    • public void attributeReplaced (HttpSessionBindingEvent hsbe)
    • public void attributeReplaced (ServletRequestAttributeEvent srae)
  • 演示监听session的属性变化
    public class MySessionAttributeListener implements HttpSessionAttributeListener {

        public void attributeAdded(HttpSessionBindingEvent arg0) {

            // arg0.getSession(); 获取事件源,也就是获取session对象.
            System.out.println(arg0.getName());
            System.out.println(arg0.getValue());
            System.out.println("向session中添加属性");
        }

        public void attributeRemoved(HttpSessionBindingEvent arg0) {
            System.out.println("从session中移除属性");
        }

        public void attributeReplaced(HttpSessionBindingEvent arg0) {
            System.out.println("将session中的属性修改");
        }

    }
  • 问题:在监听器中是否可以得到属性值?

    • 常识:在java的监听机制中,是可以在监听器中获取事件源的。
    • 我们在开发中,如果有到了事件触发机制,那么一般情况下,都可以使用
    • 方法的参数(事件对象)来获取想要的信息。
  • 思考一个问题:这些监听器在开发中有什么用?
    • 在主流中应用比较少,但是可以完成一些性能监试操作。

监听器案例

  • 功能:扫描session对象在指定时间内没有使用,人为销毁。
  • 分析:
    • 1.怎样知识session多长时间没有使用?

      • 当前时间-最后使用时间(public long getLastAccessedTime()
    • 2.什么时候开始扫描,扫描多长时间?
      • 可以使用Timer完成
  • 完成定时扫描session,如果超时没有使用,销毁案例:

    1.要将所有的session对象得到,保存到集合中。

    1.创建一个监听器 ServletContextListener,它服务器启动时,创建一个集合保存到ServletContext域。

    2.创建一个监听器 HttpSessionListener,当创建一个session时,就从ServletContext域中获取集合,将session对象储存到集合中。

    2.定时扫描

    问题:
        1.session超时,不能只销毁session,还要从集合中移除。
    
        2.我们的操作,它是多线程的,要考虑集合的同步问题。
            1.集合需要是线程安全的。
            2.需要使用迭代器进行遍历。
    

Session绑定监听器

  • 保存在Session域中的对象可以有多种状态:

    • 绑定到 Session 中;
    • 从 Session 域中解除绑定;
    • 随 Session 对象持久化到一个存储设备中(钝化);
    • 随 Session 对象从一个存储设备中恢复(活化);
  • Servlet 规范中定义了两个特殊的监听器接口来帮助JavaBean对象了解自己在 Session域中的这些状态。
    • HttpSessionBindingListener接口
    • HttpSessionActivationListener接口
    • 实现这两个接口的类不需要web.xml 文件中进行注册
  • 实现了HttpSessionBindingListener接口的 JavaBean 对象可以感知自己被绑定到 Session 中和从 Session中删除的事件
    • 当对象被绑定到 HttpSession 对象中时,web服务器调用该对象的 void valueBound(HttpSessionBindingEvent event) 方法
    • 当对象从 HttpSession 对象中解除绑定时,web服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法
  • 实现了HttpSessionActivationListener接口的 JavaBean对象可以感知自己被活化钝化的事件
    • 当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被钝化之前,web 服务器调用如下方法sessionWillPassivate(HttpSessionBindingEvent event) 方法
    • 当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被活化之后,web 服务器调用该对象的 void sessionDidActive(HttpSessionBindingEvent event)方法
    • 钝化—>将session中的javaBean保存到文件中.
    • 活化—>从文件中将javaBean直接获取。
  • 需要创建一个配置文件context.xml
    • 这个文件保存到META-INF目录下.
    <Context>
    <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1">
    <Store className="org.apache.catalina.session.FileStore" directory="it315"/>
    </Manager>
    </Context>
  • 这两个监听器特点;

    • 1.它们是由javaBean实现。
    • 2.它们不需要在web.xml文件中配置。
时间: 2024-07-31 16:15:41

Java进阶学习第二十天——分页与Listener的相关文章

Java进阶学习(2)——log4j的学习和使用

Java进阶学习(2)--log4j的学习和使用 简介Loj4j Log4j的组成 Log4j主要由三大组组件构成: Logger: 负责生成日志,并能够对日志信息进行分类筛选,通俗的讲就是决定什么日志信息应该被输出,什么日志信息应该被忽略. Appender: 定义了日志信息输出的目的地,指定日志信息应该被输出到什么地方,这些地方可以是控制台.文件或网络设备等. Layout: 指定日志信息的输出格式. 说明: 一个Logger可以有多个Appender,这意味着日志信息可以被输出到多个设备上

java进阶学习计划

断断续续使用java也已经有两年了,算是最熟悉的开发工具了.但写的代码都是以项目为导向,追求work around,还需要打好基础才能长远发展. 大致的进阶学习计划, 阶段1:深究java语法,阅读常用库的jdk源码,了解jvm机制; 阶段2:阅读基于java的开源框架源码,各种framework,container. 希望可以坚持下来,经常更新技术博客. java进阶学习计划

Java:进阶学习(1)——网络编程

Java:进阶学习(1)--网络编程 基础 Socket与ServerSocket Socket又称"套接字",网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. Socket方法 getInetAddress();    远程服务端的IP地址 getPort();    远程服务端的端口 getLocalAddress()    本地客户端的IP地址 getLocalPort()    本地客户端的端口 getInputStream();   

Java进阶学习规划

最近一直很郁闷,觉得测试的工作自己不适合,打算转Java后端,以前有点Java的基础,但是已经有快5个月没有敲代码了,学习的东西也丢的差不多了,写个规划,在4月底前把以前的知识学回来. 1.Java基础 (1)集合框架 (2)泛型 (3)并发编程 (4)反射机制 推荐书籍:Java并发编程实战 2.项目实践 (1)基础web案例(使用jsp.jdbc实现) (2)使用ssh框架进行开发(至少做两个项目) 3.深入学习 (1)Java虚拟机 (2)设计模式 推荐书籍 head first desi

Java进阶学习第五天——XML入门

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.04.14 lutianfei none onsubmit事件 控制表单提交 需要把onsubmit作用在表单上 <form onsubmit=""> 值的写法:onsubmit="return run()" run()必须要有返回值,必须返回true或者false. 如果返回是true,表单可以提交,如果返回false,表单不能提交.如果没有返回值,默认是表单提交. run(

Java进阶学习第二十二天——上传与下载

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.06.05 lutianfei none Servlet规范中 servlet有初始化参数 Filter有初始化参数 Listener没有初始化参数,要使用,在开发中一般使用<context-param> servletContext的初始化参数. 文件上传 问题:什么是文件上传?为什么使用文件上传? 就是将客户端资源,通过网络传递到服务器端. 就是因为数据比较大,我们必须通过文件上传才可以完成将数据保存到服务器端操

java进阶学习 --java网络编程一(转)

Java - 网络编程完全总结(基础介绍) 本文主要是在网络编程方面的学习总结,先主要介绍计算机网络方面的相关内容,包括计算机网络基础,OSI参考模型,TCP/IP协议簇,常见的网络协议等等,在此基础上,主要介绍Java中的网络编程. 目录 一.概述 二.计算机网络 1.网络协议 2.网络体系结构 三.OSI参考模型 四.TCP/IP参考模型 五.常见网络协议 1.TCP协议 2.UDP协议 3.HTTP协议 六.计网常见问题 一.概述 计算机网络是通过传输介质.通信设施和网络通信协议,把分散在

Java Web学习总结(13)Listener监听器

一,监听器介绍 监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动.监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行. 监听器的相关概念: 事件源 被监听的对象 监听器 监听事件源对象,事件源对象的状态的变化都会触发监听器 注册监听器 将监听器与事件源进行绑定. 响应行为 监听器监听到事件源的状态变化时 所涉及

[Android Pro] Java进阶学习:jar打包详解

jar文件听说过吗,没有?或者陌生!好,没关系,这就是我们的第一站:打包发布. 为什么会有这个玩意呢,首先,这是jar的全称:JavaTM Archive (JAR) file,是的,就是java存档文件.这有点类似zip文件,想一想它是干什么的用的呢,压缩!?没错就是要压缩,将我们原先零散的东西放到一下,重新 组织,所有这些目的只有一个:方便!好了,不用管他是怎么压缩的,我们的重点是哪些是我们要压缩的(输入),还有压缩成了什么(输出),进而将它发布(部 署). 那我们的输入(要压缩的东西)主要