• JSP常用指令


    一.指令元素
    1.page指令
    import
    session
    contentType
    buffer
    isTreadSafe
    info
    errorPage
    isErrorPage
    2.include指令
    3.taglib指令
    二.脚本元素
    1.声明元素
    2.表达式元素
    3.脚本元素
    4.注释元素
    三.标准动作元素
    1.<jsp:param>
    2.<jsp:include>
    3.<jsp:forward>
    4.<jsp:plugin>
    5.<jsp:useBean>
    6.<jsp:setProperty>
    7.<jsp:getProperty>
    四.内置对象
    1.request
    2.response 
    3.out
    4.session
    5.pageContext
    6.application
    7.config
    8.page
    9.exception
    五.JavaBeans的使用
    1.JavaBeans在JSP中的基本使用格式
    2.scope范围的具体设定
    3.session事件的运用
    4.Bean的保存与读取
    六.JSP中的文件操作
    七.JSP运行原理剖析
    -------------------------------------------------

    在早期,开发网络数据库应用程序主要采用CGI(Common Gateway Interface)技术。编写CGI程序可以使用不同的程序语言,如Perl、Visual Basic、Delphi或C/C++等。虽然CGI技术已经发展成熟而且功能强大,但由于其编程困难、效率低下、修改复杂等缺陷,所以有被新技术取代的技术。
    在这样的背景下,新的技术纷纷面世,如ASP(Active Server Page)、PHP(Personal Home Page)、JSP(Java Server Page)等。其中,JSP被许多人认为是未来最有发展前途的动态网站技术。
    JSP页面一般由HTML标签和JSP元素构成,其中的JSP元素则又是由“指令元素”、“脚本元素” 、“标准动作元素” 、“内置对象”四个部分组成。下面,就让我们一起来探究JSP的奥秘吧……

    一.    指令元素

    可以把JSP理解为用来通知JSP引擎的消息。JSP不直接生成可见的输出,用JSP指令设置JSP引擎处理JSP页面的机制。
    一般JSP指令用标签<%@…%>表示,JSP指令包括page、include和taglib。page指令是针对当前页面的指令,而include指令用来指定如何包含另外一个文件,taglib指令用来定义和访问自定义标记库。这三种指令通常都有默认值,这样开发人员就不必显式的使用每一个指令予以确认。
    1.    page指令
    page指令的设置语法格式是:<%@ page attribute1=”value1” attribute2=”value2”…%>
    下面介绍指令中包括的几个常用属性,并作简要说明。
    l    import
    import指令是所有page指令中,唯一可以多次设置的指令,而且累加每个设置。它用来指定jsp网页中所需要使用到的一些类。例如:
    <%@ page import=”java.io.*,java.util.Date”%>
    l    session
    定义当前页面是否参与http会话。当设置为”true”时,可以获得隐含名为session的对象,为”false”时,则不能。默认设置为”true”。
    l    contentType
    设置jsp网页输出时数据时,所使用的字符压缩方式,以及所使用的字符集,当编写中文网页时,设置如下:
    <%@page contentType=”text/html;charset=Gb2312”%>
    此属性的默认值为”text/html;charset=ISO-8859-1”。
    l    buffer
    设置jsp网页的缓冲区大小,默认为”8k”,如果设置为”none”,则表示不使用缓冲,所有的响应输出都将被PrintWriter直接写到ServletResponse中。
    l    isTreadSafe
    定义当前页面是否支持线程安全。如果为”true”,则该页面可能同时收到jsp引擎发出的多个请求,反之,jsp引擎会对收到的请求进行排队,当前页面在同一时刻只能处理一个请求。默认为”true”。
    l    info
    设置页面的文本信息,可以通过Servlet.getServletInfo()的方法获得该字符串。
    l    errorPage
    定义指向另一个jsp页面的URL。当页面出现一个没有被捕获的异常时,错误信息将以throw语句抛出,而被设置为错误信息网页的jsp页面,将利用exception隐含对象,取得错误信息。
    默认没有错误处理页面。    
    l    isErrorPage
    设置此jsp网页是否为错误处理页面。默认值为”false”。当设置为”true”时,jsp页面将可存取隐含的exception对象,并通过该对象取得从发生错误之网页所传出的错误信息。取得错误信息的语法如下:
    <% =exception.getMessage()%>
    ²    一个页面错误处理的例子
    产生错误的页面文件为MakeError.jsp,处理错误的页面文件为ErrorPage.jsp,它们的源程序如下:
    MakeError.jsp

    <%@ page errorPage="ErrorPage.jsp"%> 
    <html>  
    <head> 
       <title>产生错误页面</title> 
    </head> 
    <body> 
    <% 
    int i=8,j=0; 
    out.println(ij); 
    %> 
    </body> 
    </html> 
    ErrorPage.jsp 
    <%@ page isErrorPage="true"%> 
    <html>  
    <head> 
       <title>错误处理页面</title> 
    </head> 
    <body> 
    <font color=red> 
     错误原因:<%=exception.getMessage()%> 
    </font> 
    </body> 
    </html>

    运行程序MakeError.jsp的结果如下:
     
    2.    include指令
    使用include指令可以把其他的文本文件加入到当前的jsp页面,格式如下:
    <%@ include file=”header.inc”%>
    如此,则在当前页面中加入header.inc源代码然后再编译整个文件。
    可以使用include指令把一个页面分成不同的部分,最后合成一个完整的文件,使用jsp的include指令有助于实现jsp页面的模块化。
    3.    taglib指令
    (略)

    二.    脚本元素

    JSP规格提供了四种类型的脚本元素,包括:
    l    声明
    l    表达式
    l    脚本
    l    注释
    下面分别对它们进行详细叙述。
    1.    声明元素
    声明用于定义jsp页面中的变量与函数,这些经过定义的变量和函数,将成为Servlet类的属性与方法(关于Servlet请参看后文)。声明并不会产生任何的数据输出,声明时可同时设置初始值,提供给其他的声明、表达式或脚本使用。
    声明的语法格式为:

    <%! 
        //声明语句 
    %> 
    举例: 
    <%! 
    //此处定义的变量将成为此jsp页面的全局变量 
    int i = 0; 
    static int j=100; 
    String s = “注意”;  
    %> 
    <%! 
    //此处定义的函数将成为此jsp页面的公共函数 
    Public int square(int i) 

        return(i*i); 

    %>

    ²    jspInit函数与jspDestroy函数
    若要在jsp页面开始执行时进行某些数据的初始化,可以利用jspInit函数完成。此函数将在jsp页面被执行时调用,且当jsp页面重新整理时,并不会被再度执行。当关闭服务器时,jspDestroy函数将被执行,可以利用该函数进行数据的善后处理工作。下面举个简单的例子说明,文件InitDes.jsp代码如下:

    <%@ page contentType="text/html; charset=GB2312"%> 
    <%! 
    public void jspInit() 

        System.out.println("jspInit is called!"); 
    }

    public void jspDestroy() 

        System.out.println("jspDestroy is called!"); 

    %> 
    <HTML> 
    <HEAD><TITLE>jspInit函数与jspDestroy函数的使用</TITLE></HEAD> 
    <BODY> 
    <CENTER> 
    <FONT SIZE = 5 COLOR = blue>jspInit函数与jspDestroy函数的使用</FONT> 
    </CENTER> 
    <HR><BR> 
    </BODY> 
    </HTML>

    首次执行此页面时,Resin服务器输出如下:
    Resin 1.2.2 -- Tue Jan 16 09:53:18 PST 2001
    http listening to *:8080
    srun listening to 127.0.0.1:6802
    jspInit is called!
    刷新此页面数次后,Resin服务器输出仍然如上。
    此时,如果关闭服务器,则输出如下:
    Resin 1.2.2 -- Tue Jan 16 09:53:18 PST 2001
    http listening to *:8080
    srun listening to 127.0.0.1:6802
    jspInit is called!
    closing server
    jspDestroy is called!
    由此,我们得到启发,在数据库的开发过程中,可以利用jspInit函数来进行数据库的连接工作,用jspDestroy函数来进行数据库的关毕工作。下面以一个分页显示数据库内容的程序为例子,让读者进一步体会jspInit与jspDestroy的功用与好处。
    在Pages.jsp这个分页程序中,我们把数据库连接的动作写在jspInit函数中,这样,每一次重新整理页面时,就可以避免重新执行数据库的连接动作。如下:

    <%@ page contentType="text/html; charset=GB2312"  
        import="java.sql.*"%> 
    <%! 
    int PageSize = 2; //设置每张网页显示两笔记录 
    int ShowPage = 1; //设置欲显示的页数 
    int RowCount = 0; //ResultSet的记录笔数 
    int PageCount = 0; //ResultSet分页后的总页数 
    Connection con = null; 
    Statement stmt = null; 
    ResultSet rs = null;

    public void jspInit() //执行数据库与相关数据的初始化 
    {     
        try 
            { 
            Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
            //载入驱动程序类别

            con = DriverManager.getConnection("jdbc:odbc:test"); 
            //建立数据库链接

            stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, 
                           ResultSet.CONCUR_READ_ONLY); 
            //建立Statement对象, 并设置记录指标类型为可前后移动

            rs = stmt.executeQuery("SELECT * FROM products"); 
            //建立ResultSet(结果集)对象,并执行SQL语句

            rs.last(); //将指标移至最后一笔记录

            RowCount = rs.getRow(); //取得ResultSet中记录的笔数 
         
            PageCount = ((RowCount % PageSize) == 0 ?  
                    (RowCountPageSize) : (RowCountPageSize)+1); 
            //计算显示的页数 
        } 
        catch(Exception ex) 
        {     
            System.out.println(ex.toString()); 
        } 
    }

    public void jspDestroy() //执行关闭各种对象的操作 

        try 
            { 
            rs.close(); //关闭ResultSet对象 
            stmt.close(); //关闭Statement对象 
            con.close(); //关闭数据库链接对象 
        } 
        catch(Exception ex) 
        { 
            System.out.println(ex.toString()); 
        } 

    %> 
    <HTML> 
    <HEAD> 
    <TITLE>记录的分页显示</TITLE> 
    </HEAD> 
    <BODY> 
    <CENTER> 
    <FONT SIZE = 5 COLOR = blue>记录的分页显示</FONT> 
    </CENTER> 
    <HR> 
    <P></P> 
    <CENTER> 
    <% 
    String ToPage = request.getParameter("ToPage");

    //判断是否可正确取得ToPage参数,  
    //可取得则表示JSP网页应显示特定分页记录的语句 
    if(ToPage != null) 

        ShowPage = Integer.parseInt(ToPage); //取得指定显示的分页页数 
         
        //下面的if语句将判断用户输入的页数是否正确 
        if(ShowPage > PageCount) 
        { //判断指定页数是否大于总页数, 是则设置显示最后一页 
            ShowPage = PageCount; 
        } 
        else if(ShowPage <= 0) 
        { //若指定页数小于0, 则设置显示第一页的记录 
            ShowPage = 1; 
        } 
    }

    rs.absolute((ShowPage - 1) * PageSize + 1);  
    //计算欲显示页的第一笔记录位置 
    %> 
    <H3>目前在第<FONT SIZE = 4 COLOR = red> 
    <%= ShowPage %></FONT>页, 共有 
    <FONT SIZE = 4 COLOR = red> 
    <%= PageCount %></FONT>页</H3> 
    <P></P> 
    <% 
    //利用For循环配合PageSize属性输出一页中的记录 
    for(int i = 1; i <= PageSize; i++) 

        %> 
        <TABLE border=1 bordercolor=RoyalBlue bgcolor=LightBlue> 
            <TR><TD bgcolor=LightYellow width= 100> 
            <B>商品名</B></TD> 
            <TD width= 100><B><%= rs.getString("product_name") %> 
            </B></TD> 
            <TD bgcolor=LightYellow width= 100> 
            <B>价格</B></TD> 
            <TD width= 100><B><%= rs.getInt("price") %> 
            </B></TD> 
            <TD bgcolor=LightYellow width= 100> 
            <B>描述</B></TD> 
            <TD width= 100><B><%= rs.getString("description") %> 
            </B></TD> 
            </TR> 
        </TABLE><BR> 
        <% 
        //下面的if判断语句用于防止输出最后一页记录时,  
        //将记录指标移至最后一笔记录之后 
        if(!rs.next())     //判断是否到达最后一笔记录 
            break;  //跳出for循环 

    %> 
    <TABLE> 
    <TR valign=baseline align=center> 
    <% 
    //判断目前所在分页是否为第一页, 
    //不是则显示到第一页与上一页的超链接 
    if(ShowPage != 1) 

    //下面建立的各超链接将链接至自己,  
    //并将欲显示的分页以ToPage参数传递给自己 
        %> 
        <TD Width=150> 
        <A Href=Pages.jsp?ToPage=<%= 1 %>>到第一页</A> 
        </TD> 
        <TD Width=150> 
        <A Href=Pages.jsp?ToPage=<%= ShowPage - 1 %>>到上一页</A> 
        </TD> 
        <% 
    }

    //判断目前所在分页是否为最后一页, 
    //不是则显示到最后一页与下一页的超链接 
    if(ShowPage != PageCount) 

    //下面建立的各超链接将链接至自己,  
    //并将欲显示的分页以ToPage参数传递自己 
        %>     
        <TD Width=150> 
        <A Href=Pages.jsp?ToPage=<%= ShowPage + 1%>>到下一页</A> 
        </TD>   
        <TD Width=150> 
        <A Href=Pages.jsp?ToPage=<%= PageCount %>>到最后一页</A> 
        </TD> 
        <% 

    %> 
    <TD Width=150> 
    <FORM action=Pages.jsp method=POST> 
    到  
    <!-- 
    供用户输入欲查看页数的文字方块, 预设值为目前所在的分页,  
    当用户在此文字方块中完成数据输入后按下 Enter 即可将数据送出, 
    相当于按下Submit按钮, 因此此表单中将省略Submit按钮 
    --> 
    <INPUT type="text" name=ToPage style="HEIGHT: 25px; WIDTH: 40px" 
     value=<%= ShowPage%> > 页 
    </FORM></TD></TR> 
    </TABLE> 
    </CENTER> 
    </BODY> 
    </HTML>

    执行后,结果如下图:
     
    2.    表达式元素
    表达式是一个简化了的out.println语句。
    表达式的语法格式为:
    <%=//要输出的数据%>
    举例:
    <%=square(5)%>
    3.    脚本元素
    脚本是java程序的一段代码,只要符合java语法的语句都可以写在这里,它是在请求时期执行的,它可以使用jsp页面所定义的变量、方法、表达式或JavaBeans。
    脚本的语法格式为:

    <% 
        //java代码 
    %> 
    举例: 
    <% 
    if(age<18) 

       out.println(“你是未成年人!!!!”); 

    else 

       out.println(“你已经成年了!!!!”); 

    %>

    4.    注释元素
    用来对程序进行说明注释。注释大体有下列三种格式:
    <!—客户端注释à
    <!--<%=客户端动态注释%>-->
    <%--服务器端注释--%>

    三.    标准动作元素

    标准动作元素用于执行一些常用的JSP页面动作,例如:将页面转向、使用JavaBean、设置JavaBean的属性等。在JSP中,标准动作元素共有以下几种:
    l    <jsp:param>
    l    <jsp:include>
    l    <jsp:forward>
    l    <jsp:plugin>
    l    <jsp:useBean>
    l    <jsp:setProperty>
    l    <jsp:getProperty>
    其中<jsp:useBean>、<jsp:setProperty>、<jsp:getProperty>这三个是专门用来操作JavaBeans的。
    下面分别介绍它们。
    1.    <jsp:param>
    <jsp:param>动作用于传递参数,必须配合<jsp:include>、<jsp:forward>、<jsp:plugin>动作一起使用。
    语法格式:
    <jsp:param name = “name1” value = “value1”/>
    2.    <jsp:include>
    <jsp:include>动作用于动态加载HTML页面或者JSP页面。
    语法格式:
    <jsp:include page = “网页路径”>
    <jsp:param name = “name1” value = “value1”/>
    <jsp:param name = “name2” value = “value2”/>
    <jsp:include/>
    在jsp页面中,可以利用下面的语法取得返回的参数:
    request.getParameter(“name1”);
    若不传递参数时,则语法格式如下:
    <jsp:include page = “网页路径”/>
    举例:
    a.jsp页面代码如下:

    <jsp:include page = "b.jsp"> 
        <jsp:param name = "name1" value = "value1"/> 
        <jsp:param name = "name2" value = "value2"/> 
    </jsp:include>

    b.jsp页面代码如下:
    名字1、;<%=request.getParameter("name1")%>
    <hr color=red>
    名字2、;<%=request.getParameter("name2")%>
    执行结果如下:
     
    “include标准动作”和“include指令”的差别在于:“include标准动作”包含的页面在运行时被加入,而“include指令”在编译时就被加入了。
    3.    <jsp:forward>
    <jsp:forward>动作用于将浏览器显示的页面导向到另一个HTML页面或者jsp页面。
    语法格式:
    <jsp:forward page = “网页路径”/>
    当然,<jsp:forward>动作中也可以加入<jsp:param>参数,其设置和获得参数的方法与<jsp:include>类似。
    4.    <jsp:plugin>
    <jsp:plugin>动作用于加载applet,用途与HTML语法中的<Applet>及<Object>标记相同。该动作是在客户端执行的,这里就不作介绍了。
    5.    <jsp:useBean>
    (见后文的“JavaBeans”的使用)
    6.    <jsp:setProperty>
    (见后文的“JavaBeans”的使用)
    7.    <jsp:getProperty>
    (见后文的“JavaBeans”的使用)

    四.    内置对象

    在jsp页面中有一些已经完成定义的对象,称之为内置对象。这些对象可以不经过定义就直接使用,因为它们是由jsp页面自己定义的。
    jsp程序常用的内建对象有如下几个:request、response、out、session、pageContext、application、config、page、exception。你可以在jsp页面中直接使用它们,用以加强jsp程序的功能。
    下面分别介绍它们。
    1.    request
    与request相联系的是HttpServletRequest类。通过getParameter方法可以获得相应的参数值。
    2.    response 
    与response相联系的是HttpServletResponse类。表示Web页面针对请求的应答。
    3.    out
    与out相联系的是PrintWrite类。可以使用此对象将内容输出到页面中。
    4.    session
    与session相联系的是HttpSession类。用来传递客户的会话内容。
    5.    pageContext
    与pageContext相联系的是pageContext类。用它能方便的访问本页面中设置的共享数据。
    6.    application
    与application相联系的是ServletContext类。用它能够实现应用程序级别的数据共享。
    7.    config
    与config相联系的是ServletConfig类。用来在jsp页面范围内处理jsp配置。
    8.    page
    代表jsp页面编译成的Servlet实例,一般不用。
    9.    exception
    与exception相联系的是Throwable类。用来捕获jsp执行时抛出的异常。
    五.    JavaBeans的使用
    JavaBeans是运行于java虚拟机上的100%的纯java组件,它的概念描述很类似于Microsoft的COM组件概念。
    JavaBeans传统的应用在于可视化领域,如AWT下的应用。其实,基于AWT的任何java程序已经是一个Bean,完全可以把它当作一个组件来使用。
    现在,JavaBeans更多的应用在不可视化领域,它在服务器端应用方面表现出了越来越强的生命力。不可视化的JavaBeans在JSP程序中用来封装事务逻辑,可以很好的实现业务逻辑和前台程序的分离,使得系统具有更好的健壮性和灵活性。
    JavaBeans描述了JDK1.1以前的java所没有的东西,因此,运行JavaBeans最小的需求是JDK1.1或者以上的版本。
    1.    JavaBeans在JSP中的基本使用格式
    l    在JSP中调用JavaBeans的格式
    //加载Bean
    <jsp:useBean id = “名称” scope = “有效范围” class = “Bean类位置”/>

    //设定Bean属性(两种方法)
    //方法一:“标签设定”
    <jsp:setProperty name = “名称” property = “属性” value = “值”/>
    //方法二:“方法设定(用于java程序中)”
    Bean对象名称.set属性(值)

    //获取Bean属性(两种方法)
    //方法一:“标签获取”
    <jsp:getProperty name = “名称” property = “属性”/>
    //方法二:“方法获取(用于java程序中)”
    Bean对象名称.get属性()
    l    JavaBean编写的格式
    //定义Bean类所属于的包

    package 包名

    //定义为公开等级的类,并且类名称与源代码文件名相同 
    public class类名 

       //Bean类的属性,其等级定义为private 
       private 数据类型 属性名

       //用来初始化的构造函数 
       //Bean的构造函数无输入参数 
       public 类名 
       {  }


       //以setXXX函数,作为设定Bean类属性的接口 
       public void set属性名称(数据类型 参数) 
       { 
          this.属性 = 参数 
       }

       //以getXXX函数,作为取得Bean类属性的接口 
       public void get属性名称() 
       { 
          return this.属性 
       } 
    }

    ²    一个简单的使用JavaBeans的例子
    Bean文件LoginData.java的源代码如下:

    package j2ee.jsp; 
    //定义Bean所属的包

    public class LoginData 

        //Bean属性 
        private String Name = ""; 
        private String Pwd = "";

        public LoginData()  //构造函数 
        {         
        }

        //以下为设定Bean属性的方法 
        public void setLoginName(String name) 
        { this.Name = name; } 
        public void setPassword(String pwd) 
        { this.Pwd = pwd; }

        //以下为取得Bean属性的方法 
        public String getLoginName() 
        { return this.Name; } 
        public String getPassword() 
        { return this.Pwd; } 
    }

    调用Bean的jsp文件UseBean.jsp源程序如下:

    <%@ page contentType="text/html; charset=GB2312" %> 
    <HTML> 
    <HEAD> 
    <TITLE>使用Beans</TITLE> 
    </HEAD> 
    <BODY> 
    <CENTER> 
    <FONT SIZE = 5 COLOR = blue>使用Beans</FONT> 
    </CENTER> 
    <HR> 
    <P></P> 
    <H2> 
    <jsp:useBean id="login" scope="application"   
        class="j2ee.jsp.LoginData"/> 
    <jsp:setProperty name="login"  
        property="loginName" value="最后的决定"/> 
    <% 
    login.setPassword("123456"); //调用Bean对象的方法, 设定属性 
    %>

    <Font color = red>LoginName</Font>属性值为 
    <Font color = blue> 
    <jsp:getProperty name="login" property="loginName"/> 
    </Font><BR> 
    <Font color = red>Password</Font>属性值为 
    <Font color = blue> 
    <%--以调用Bean对象方法的方式取得属性--%> 
    <%= login.getPassword() %></Font> 
    </BODY> 
    </HTML>

    运行结果如下:
     
    在前面的使用中,有两点值得注意:
    (1)    Bean中各个方法名的“命名规则及大小写”与调用Bean时的“方法名规则及大小写”之间的对应关系需要注意。
    (2)    Beans的存放目录将随选用服务器的不同而不同。以resin服务器而言,Beans默认定义存放在application-programmeWEB-INFclasses子目录中。
    2.    scope范围的具体设定
    JavaBeans可以定义四种生命周期?D?Dpage、request、session与application,将分别运用pageContext、request、session、application四种对象的setAttribute方法,将JavaBeans对象保存在该对象中。下面分别说明:
    l    Page的有效范围仅仅涵盖使用JavaBeans的页面,一旦你离开此页面,JavaBeans对象的实体也将随之消失。
    l    Request的有效范围仅及于使用JavaBeans的请求而已,一旦你结束该页面的请求,JavaBeans对象的实体也将随之消失。
    l    Session的有效范围涵盖了整个用户会话时期。在用户会话期间,JavaBeans对象的实体均不会消失。当用户会话结束时,JavaBeans对象的实体才会消失。
    l    Application的有效范围则涵盖了整个应用程序时期。在应用程序期间,JavaBeans对象的实体均不会消失。只有当应用程序结束时,JavaBeans对象的实体才会消失。
    下面,举一个简单的例子,对Request与Session两种生命周期做具体的演示。
    Bean文件counter.java的源代码如下:

    package j2ee.jsp; 
    public class counter 

        private int count = 0; 
         
        public void setCount(int c) 
        { 
            this.count = c; 
        } 
         
        public int getCount() 
        { 
            this.count++; 
            return this.count; 
        } 
    }    

    Request实例
    两个jsp文件b1.jsp与b2.jsp代码分别如下:
    b1.jsp

    <jsp:useBean id="counter" scope="request" class="j2ee.jsp.counter"/>

    <% 
    counter.setCount(100); 
    %>

    <jsp:forward page="b2.jsp"/> 
    b2.jsp 
    <jsp:useBean id="counter" scope="request" class="j2ee.jsp.counter"/>

    <% 
    out.println(counter.getCount()); 
    %>

    运行结果如下:
     
    Session实例
    两个jsp文件c1.jsp与c2.jsp代码分别如下:
    c1.jsp
    <jsp:useBean id="counter" scope="session" class="j2ee.jsp.counter"/>

    <%
    out.println(counter.getCount());
    %>

    <a href="c2.jsp" target="_blank">c2.jsp</a>
    c2.jsp
    <jsp:useBean id="counter" scope="session" class="j2ee.jsp.counter"/>

    <%
    out.println(counter.getCount());
    %>
    运行结果如下:
     
    3.    session事件的运用
    在jsp页面中,将Bean对象保存至session对象时,可以定义Bean响应HttpSessionBindingEvent事件。当Bean对象加入session、Bean从session中删除以及session对象终止时,将会触发此事件。因此,我们可以利用这两个事件,执行数据起始、善后的工作。
    由此,我们可以想到,把jsp页面中最耗费服务器资源的数据库连接工作放入HttpSessionBindingEvent事件中。当一个会话开始时,建立一个“数据库连机”,随后的整个会话过程中,所有与数据库相关的操作均使用这一个“连机”,这样,就避免了每执行一次数据库操作就产生一个数据库连机的巨大消耗。当此会话结束时,再关闭释放这个“数据库连机”。
    如果要Bean对象响应HttpSessionBindingEvent事件,则该Bean对象必须实现HttpSessionBindingListener接口,并且定义响应会话开始的valueBound方法以及响应会话结束的valueUnbound方法。
    现在,我们来实做一个例子,首先,建立一个“用来建立会话级别数据库联机”的Bean文件DBCon.java,它的源代码如下所示:

    /* 
     * 文件名:DBCon.java 
     * 
     * 类名:DBCon 
     * 
     * 所属包:j2ee.jsp 
     * 
     * 导入包:java.sql.*;javax.servlet.http.*;  
     * 
     * 作者:杨?? 
     * 
     * 创建时间:2003.12.9 
     * 
     * 用途描述:在此JavaBean中建立会话级别的数据库联机,供会话过程中的各个jsp页面使用 
     *  
     * 版本号:1.0 
     * 
     */

    package j2ee.jsp;

    import javax.servlet.http.*;  
    import java.sql.*;

    //定义DBCon类别实做HttpSessionBindingListener介面 
    public class DBCon implements HttpSessionBindingListener 

        //与数据库连结有关的Bean属性 
        private Connection con = null; 
         
          /** 
           * 方法名:BulidConnection 
           * 级别:private 
           * @param     (无) 
           * @return    (无) 
           * @throws    (无) 
           * 作用:建立一个数据库联机 
           */ 
        private void BulidConnection() 
        { 
            try 
            { 
                System.out.println("BulidConnection()方法被调用");      
                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
                //载入驱动程式类别 
         
                con = DriverManager.getConnection("jdbc:odbc:test"); 
                //建立数据库连线             
            } 
            catch(Exception ex) 
            {     
                System.out.println(ex.toString()); 
            }         
        }

          /** 
           * 方法名:close 
           * 级别:private 
           * @param     (无) 
           * @return    (无) 
           * @throws    (无) 
           * 作用:关闭数据库联机 
           */ 
        private void close() 
        { 
            try 
            { 
                con.close(); //关闭Connection对象         
                con =  null; 
            } 
            catch(SQLException sex) 
            {     
                System.out.println(sex.toString()); 
            }     
        }

          /** 
           * 方法名:getConnection 
           * 级别:public 
           * @param     (无) 
           * @return    Connection     数据库联机 
           * @throws    (无) 
           * 作用:返回一个数据库联机 
           */ 
        public Connection getConnection() 
        {  
            //若con为null时, 重新建立数据库连结 
            if(con == null) 
                BulidConnection();

            return this.con; 
        }    

          /** 
           * 方法名:valueBound 
           * 级别:public 
           * @param     HttpSessionBindingEvent     事件 
           * @return    (无) 
           * @throws    (无) 
           * 作用:建立一个数据库联机,并输出相关信息 
           */ 
        public void valueBound(HttpSessionBindingEvent event) 
           { 
             BulidConnection(); 
                System.out.println("会话级别的数据库连接已经建立!!!"); 
           }

          /** 
           * 方法名:valueUnbound 
           * 级别:public 
           * @param     HttpSessionBindingEvent     事件 
           * @return    (无) 
           * @throws    (无) 
           * 作用:关闭一个数据库联机,并输出相关信息 
           */ 
        public void valueUnbound(HttpSessionBindingEvent event) 
        { 
            if(con != null) 
                close(); //呼叫close方法 
                System.out.println("会话级别的数据库连接已经关闭!!!"); 
        } 
    }

    编译这个Bean源文件。注意,编译前要设定好classpath的路径,使得它所包含的类库中有javax.servlet.http.*包。
    然后,建立两个用来测试此Bean的jsp页面文件DBBean1.jsp与DBBean2.jsp,它们的程序代码差不多,都是用来显示数据库内容的,现在就只列出DBBean1.jsp的源文件,如下:

    <%@ page contentType="text/html; charset=GB2312"  
        import="java.sql.*"%> 
    <HTML> 
    <HEAD> 
    <TITLE>利用Bean对象建立数据库链接</TITLE> 
    </HEAD> 
    <BODY> 
    <CENTER> 
    <FONT SIZE = 5 COLOR = blue> 
    利用Bean对象建立数据库链接 
    </FONT> 
    </CENTER> 
    <HR> 
    <P></P>

    <CENTER> 
    <%--起始建立数据库链接的Bean对象--%> 
    <jsp:useBean id="ConBean" scope="session"   
        class="j2ee.jsp.DBCon"/> 
    <% 
    Connection con = ConBean.getConnection(); 
    //从Bean对象取得已完成建立的数据库链接

    Statement stmt = con.createStatement(); 
    //建立Statement对象

    ResultSet rs = stmt.executeQuery("SELECT product_name, price FROM products"); 
    //建立ResultSet(结果集)对象,并执行SQL叙述 
    %> 
    <TABLE  bgcolor=DodgerBlue> 
        <TR  bgcolor=SkyBlue>     
        <TD><B>书  名</B></TD><TD><B>价   格</B></TD>     
        </TR>     
        <% 
        //利用while循环将数据表中的记录列出 
        while (rs.next()) 
        { 
            %> 
            <TR bgcolor=LightGoldenrodYellow>         
            <TD><B><%= rs.getString("product_name") %></B></TD> 
            <TD><B><%= rs.getString("price") %></B></TD>             
            </TR> 
            <% 
        }

        rs.close(); //关闭记录集 
        stmt.close(); //关闭Statement对象 
    %>     
    </TABLE> 
    </CENTER> 
    <a href="DBBean2.jsp">DBBean2.jsp</a> 
    </BODY> 
    </HTML>

  • 相关阅读:
    UDP的坏处
    进程控制块(Process Control Block, PCB)
    分布式中一些关键概念的解释
    线程池的设计实现
    [原创] 同步、异步、阻塞、非阻塞详解
    常用场景对文件状态的影响
    echo使用说明,参数详解
    Linux下源码安装ffmpeg及ffmpeg的简单使用说明
    127.0.0.1、0.0.0.0和本机IP地址的区别和使用
    链路层的简介和MTU
  • 原文地址:https://www.cnblogs.com/wzd5230/p/5547640.html
Copyright © 2020-2023  润新知