12Java Bean

 Java Bean


 

 

   JavaBean是一种组件体系结构。实际上,JavaBean就是一个Java类,这个类可以重复地使用。我们可以把JavaBean看成是一个黑盒子,即只需要知道其功能而不必管其内部结构的软件设备。例如,用JSP页面对数据库操作时,每个JSP页面都要使用代码片段写一段连接数据库的相同代码,这样会造成页面难以维护等缺点。那么比较好的方法就是把数据库操作相关的代码封装在JavaBean组件中,由JavaBean执行后台的数据库操作,JSP页面只是来显示最终结果。这样,每个页面只需要调用这个JavaBean就可以访问操作数据库,而不需要自己写代码来访问和操作数据库了。

    下面我们就来通过访问和操作数据库的例子来看看JavaBean的使用。

    首先,我们新建数据库test,并建立表ms_user。表结构如图7.4所示。

                       

图7.4

    接着,我们将“mysql-connector-java-5.0.5-bin.jar”放入“WEB-INF/lib”目录中,并将其导入项目中。

    然后,我们来看看代码,首先,我们写一个检索ms_user表中所有数据项目,并把检索出来的结果表示出来的页面selinfo.jsp。代码如例7.5。

 

<%@ page language="java" contentType="text/html;   charset=UTF-8"

      pageEncoding="UTF-8"%>

<%@page import="java.sql.Connection"%>

<%@page import="java.sql.Statement"%>

<%@page import="java.sql.DriverManager"%>

<%@page import="java.sql.ResultSet"%>

<html>

<head>

<title>检索数据</title>

</head>

<body>

<%

    // 定义数据库用变量

    Connection conn = null;

    Statement stmt = null;

    ResultSet rs = null;

    // 连接数据库

    Class.forName("com.mysql.jdbc.Driver");

    conn = DriverManager.getConnection(

            "jdbc:mysql://localhost:3306/test", "root", "password");

    // 检索数据

    stmt = conn.createStatement();

    rs = stmt.executeQuery(

"SELECT ID, USER_NAME, PASSWORD, SEX FROM ms_user");

    // 表示数据

    while (rs.next()) {

        out.print(rs.getString(1) + "&nbsp;&nbsp;");

        out.print(rs.getString(2) + "&nbsp;&nbsp;");

        out.print(rs.getString(3) + "&nbsp;&nbsp;");

        out.print(rs.getString(4) + "<br>");

    }

    // 关闭数据库连接

    rs.close();

    stmt.close();

    conn.close();

%>

</body>

</html>

例7.5

    我们再来写一个向数据库中保存一条记录的页面insinfo.jsp。如例7.6所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

      pageEncoding="UTF-8"%>

<%@page import="java.sql.Connection"%>

<%@page import="java.sql.Statement"%>

<%@page import="java.sql.DriverManager"%><html>

<head>

<title>保存数据</title>

</head>

<body>

<%

    // 定义数据库用变量

    Connection conn = null;

    Statement stmt = null;

    // 连接数据库

    Class.forName("com.mysql.jdbc.Driver");

    conn = DriverManager.getConnection(

            "jdbc:mysql://localhost:3306/test", "root", "password");

    // 保存数据

    stmt = conn.createStatement();

    int cnt = stmt.executeUpdate(

            "INSERT INTO ms_user(USER_NAME, PASSWORD, SEX)"

            + "VALUES('test', '123', '男')");

    // 关闭数据库连接

    stmt.close();

    conn.close();

%>

我们追加了<%=cnt%>条数据记录。

</body>

</html>

例7.6

    我们分别来执行这两个页面,执行结果如图7.5,图7.6所示。

 

图7.5

 

图7.6

    我们可以看到,只要我们需要访问数据库的时候,就需要上边灰色阴影部分的代码,并且,每个JSP页面中都要写这一段相同的代码,这样,可维护性和代码的重用性就得不到满足,而且,JSP页面应该尽量少写入大量的逻辑代码。这样,我们就需要使用JavaBean。

    我们来演示如何使用JavaBean。首先建立获得数据库连接的JavaBean,如例7.7所示。

/*

 * DBConnection.java

 * 功能:获得数据库连接

 */

package com.jy.sample.javabean;

 

import java.sql.Connection;

import java.sql.DriverManager;

 

/**

 * 获得数据库连接.

 * @author JY

 */

public class DBConnection {

    /** 数据库连接. */

    private Connection conn = null;

 

    /**

     * 获取数据库连接.

     * @return 数据库连接

     */

    public Connection getConn() {

        try {

            // 连接数据库

            Class.forName("com.mysql.jdbc.Driver");

            conn = DriverManager.getConnection(

                    "jdbc:mysql://localhost:3306/test", "root", "password");

        // 异常处理

        } catch (Exception e) {

            e.printStackTrace();

        }

        return conn;

    }

}

例7.7

    下面我们来修改selinfo.jsp,修改后的代码如例7.8所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

      pageEncoding="UTF-8"%>

<%@page import="java.sql.Connection"%>

<%@page import="java.sql.Statement"%>

<%@page import="java.sql.ResultSet"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>检索数据</title>

</head>

<body>

<jsp:useBean id="sel" class="com.jy.sample.javabean.DBConnection"/>

<%

    // 定义数据库用变量

    Statement stmt = null;

    ResultSet rs = null;

    // 连接数据库

    Connection conn = sel.getConn();

    // 检索数据

    stmt = conn.createStatement();

    rs = stmt.executeQuery(

"SELECT ID, USER_NAME, PASSWORD, SEX FROM ms_user");

    // 表示数据

    while (rs.next()) {

        out.print(rs.getString(1) + "&nbsp;&nbsp;");

        out.print(rs.getString(2) + "&nbsp;&nbsp;");

        out.print(rs.getString(3) + "&nbsp;&nbsp;");

        out.print(rs.getString(4) + "<br>");

    }

    // 关闭数据库连接

    rs.close();

    stmt.close();

    conn.close();

%>

</body>

</html>

例7.8

    我们再来看看insinfo.jsp修改后的代码,如例7.9所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

      pageEncoding="UTF-8"%>

<%@page import="java.sql.Connection"%>

<%@page import="java.sql.Statement"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>保存数据</title>

</head>

<body>

<jsp:useBean id="ins" class="com.jy.sample.javabean.DBConnection"/>

<%

    // 定义数据库用变量

    Statement stmt = null;

    // 连接数据库

    Connection conn = ins.getConn();

    // 保存数据

    stmt = conn.createStatement();

    int cnt = stmt.executeUpdate(

            "INSERT INTO ms_user(USER_NAME, PASSWORD, SEX)"

            + "VALUES('test', '123', '男')");

    // 关闭数据库连接

    stmt.close();

    conn.close();

%>

我们追加了<%=cnt%>条数据记录。

</body>

</html>

例7.9

    运行结果和之前的结果一样,我们不再赘述,通过上边代码看到,我们使用JavaBean实现了代码重用,在JSP页面中,我们只需要声明JavaBean并调用JavaBean的方法,如灰色阴影部分,而不需要去管JavaBean中是怎么连接的数据库的。而且,如果以后我们需要更换数据库或更换用户名密码,只需要更改JavaBean即可,不需要更改任何页面。

    JavaBean除了具有Java语言可移植、功能强、安全、简洁、模块化、扩展性、灵活性、容易开发和平台无关性等优势特色外,还有以下特点:

  • JavaBean的类必须是具体的和公共的,并且具有无参数的构造器。
  • JavaBean属性是私有的,要通过提供符合一致性设计模式的公共方法进行访问。
  • JavaBean处理表单方便,只要JavaBean属性和表单控件名称吻合,采用<jsp:useBean>标签就可以直接得到表单提交的参数。
  • 减少JSP中Java代码的夹杂。在JSP中夹杂大量Java语句,不仅降低了程序的可读性、安全性、可维护性和模块化程度,应当将这些语句分离出来以JavaBean的形式使用。
  • 实现事务处理逻辑与显示逻辑的分离。MVC(Model-View-Controllor的缩写)是一种三层体系结构模式,能很好地实现视图和数据的分离,他们分别对应数据层、表示层和业务逻辑层,其最大的优点是可合理分工,加快开发速度以及提高系统的可扩展性重用性以及可维护性。使用JavaBean,可以方便地实现MVC模式。

    在上面例子中,我们用到了<jsp:useBean>动作,我们现在就来讲解与JavaBean相关的标准动作。

7.3.1  <jsp:useBean>

    如果要在JSP页面中调用JavaBean,就必须用到<jsp:useBean>这个动作。

    <jsp:useBean>的作用是在页面中使用JavaBean之前,必须告诉JSP容器JavaBean的类型,并将其与一个名字相关联,也就是说,必须声明这个JavaBean。

    <jsp:useBean>的常见用法如下:

<jsp:useBean   id=”BeanName” class=”BeanClass”

                                scope=”page|request|session|application”/>

    <jsp:useBean>将创建一个class属性所指定的JavaBean类的一个实例,并将其与id属性所指定的名称相关联。这个名字在此页面必须唯一,而且必须是一个合法的Java变量名;它必须以一个字母开头,而且不能包含诸如点号、加号等特殊字符。

    对于<jsp:useBean>的scope属性,用来指定这个JavaBean的范围,其四种范围和前边一章讲述的隐式对象的范围是一样的,下面我们来举例子来说明。

    我们来创建一个Counter.java的JavaBean。设定一个int类型的count变量,用来显示浏览次数,默认为0。如例7.10所示。

/*

 * Counter.java

 * 功能:计数器

 */

package com.jy.sample.javabean;

 

/**

 * 计数器.

 * @author JY

 */

public class Counter {

 

    /** 计数器. */

    private int count = 0;

 

    /**

     * 获得计数器.

     * @return 计数器

     */

    public int getCount() {

        count++;

        return count;

    }

 

    /**

     * 设置计数器.

     * @param newCount 计数器

     */

    public void setCount(int newCount) {

        this.count = newCount;

    }

}

例7.10

    我们再来创建counter.jsp。来调用计数器JavaBean。在这里我们首先使用page范围。我们只需要设置<jsp:useBean>的scope属性为“page”即可,这样,这个JavaBean的生命周期只在一个页面里,只能在同一个页面中存取、利用这个JavaBean。若程序涉及其他页面时,JSP容器会自动释放其内存,结束其生命周期。counter.jsp的代码如例7.11。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

      pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>jsp:useBean范围</title>

</head>

<body>

<jsp:useBean id="counter" class="com.jy.sample.javabean.Counter" scope="page"/>

<p>您已访问<jsp:getProperty property="count" name="counter"/>次</p>

<p>欢迎再次访问</p>

</body>

</html>

例7.11

    当我们执行counter.jsp的时候,主要看看刷新页面是的变化,在page范围时,重复执行时,显示出来的值永远是1,不会递增,如图7.7所示。这是由于页面刷新后,JSP容器会将之前page范围的JavaBean删除掉,然后再重新产生一个新的Counter JavaBean,因此它永远会保持为1。不过,如果范围是session或是application时,则会产生不同的结果,后面部分我们来举例说明。

注意:这里我们使用了<jsp:getProperty>,在这里我们只要知道用它来获得JavaBean中定义变量的值即可,它将和<jsp:setProperty>在后面几节中讲解。

 

图7.7

    下面我们来修改例7.11。我们将例7.11中灰色背景部分改成scope=“session”,在此执行counter.jsp,并刷新画面。加入我们刷新了5次,则页面显示如图7.8所示。但如果我们打开新的浏览器来执行counter.jsp,则会发现数字又会从1开始往上递增。

 

图7.8

    我们再来看看application范围,我们继续修改例7.11,scope属性从“session”变为“application”,重新执行counter.jsp。我们看到的结果和设为“session”时一样,但是与session不同的是,当打开新的浏览器来执行counter.jsp时,数字不会从1开始递增,而是顺着前边浏览器的数值继续递增。这里,我们不再贴图,有兴趣的读者可以自行试验。

    我们现在来看看request范围的情况,当使用<jsp:include>和<jsp:forward>时,所有范围为page的JavaBean在新的或是包含进来的页面中都没有办法呗存取。若希望能够存取此JavaBean,它的范围就要设置成“request”。request范围的JavaBean,其存取范围除了本页面以外,当使用<jsp:include>或<jsp:forward>时,被include或forward的页面,也可以存取到原来页面产生的JavaBean。

    我们现在举例说明,首先我们定义一个counterreq.jsp。代码如例7.12所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

      pageEncoding="UTF-8"%>

<jsp:useBean id="counter" class="com.jy.sample.javabean.Counter"   scope="request"/>

Hello...感谢您<jsp:getProperty property="count" name="counter"/>次访问

例7.12

    接着,我们来修改例7.11,我们将<jsp:useBean>的scope属性设为“request”,然后追加代码<jsp:include page=“counterreq.jsp”flush=“true”>,修正后的代码如例7.13所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

      pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>jsp:useBean范围</title>

</head>

<body>

<jsp:useBean id="counter" class="com.jy.sample.javabean.Counter"   scope="request"/>

<p>您已访问<jsp:getProperty property="count" name="counter"/>次</p>

<p>欢迎再次访问</p>

<jsp:include page="counterreq.jsp"/>

</body>

</html>

例7.13

    我们来看执行结果,如图7.9所示。

 

图7.9

    从图7.9可以看到,counterreq.jsp已经加入到counter.jsp之中,而counterreq.jsp的访问次数为2,这有很重要的意义:因为程序如果调用Counter.java的getCount()方法时,count数会先自动加1,然后再显示出来,而在Counter.jsp中调用过一次getCount()方法,然后在counterreq.jsp中又调用到了同一个JavaBean的getCount()方法,因此其结果分别为1和2。

    在本节的例子中,我们用到了<jsp:getProperty>,下面我们就来介绍它。

7.3.2  <jsp:getProperty>

    若要取得JavaBean中的属性值,我们可以使用<jsp:getProperty>,其使用语法如下:

<jsp:getProperty   name=”beanName” property=”beanProperty”/>

    因此,其使用方法很简单,name就是<jsp:useBean>的id,因此,这两个要一样,而property就是想要取到的属性值,即JavaBean中定义的变量。

    <jsp:getProperty>拥有数据类型自动转换功能,它将各类型属性都转化为String类型(通过各类型的toString()方法),然后显示到网页上。<jsp:getProperty>的使用在上节已经提到过了,这里就不再举例了。

    我们知道了如何声明JavaBean(<jsp:useBean>)和如何获得JavaBean的属性(<jsp:getProperty>),那么我们怎么设置JavaBean的属性呢?我们现在就来学习。

7.3.3  <jsp:setProperty>

    这一节,我们来学习如何设定JavaBean的属性值,首先,我们来介绍下自省机制。所谓的自省机制是指:当服务器接收到请求时,它根据请求的参数名称,自动设定与JavaBean相同的属性名称的值。

    现在我们来看看<jsp:setProperty>的四种写法:

<jsp:setProperty   name="beanNm" property="*" />

<jsp:setProperty   name=" beanNm" property="propertyNm" />

<jsp:setProperty   name="beanNm" property="propertyNm" param="paramNm"/>

<jsp:setProperty   name="beanNm" property="propertyNm" value="val"   />

 

    其中,name就是<jsp:useBean>的id,因此name要和<jsp:useBean>的id一样。第一种写法:由窗体传来的参数值,通过自省机制,设定所有的属性值;第二种写法也是通过自省机制,只不过设定propertyNm的属性值;第三种写法,由窗体传来的参数名称为paramNm的值,传给属性名称为propertyNm的属性;第四种写法弹性最大,它可以通过value,动态设定JavaBean的属性。

    下面我们通过一个例子来了解这四种方法的差别。首先我们建立一个JavaBean,命名为UserBean.java。代码如例7.14。

/*

 * UserBean.java

 * 功能:用户信息类

 */

package com.jy.sample.javabean;

 

/**

 * 用户信息类.

 * @author JY

 */

public class UserBean {

 

    /** ID. */

    private Long id = null;

 

    /** Name. */

    private String name = null;

 

    /**

     * 获得ID.

     * @return ID

     */

    public Long getId() {

        return id;

    }

 

    /**

     * 设置ID.

     * @param newId ID

     */

    public void setId(Long newId) {

        this.id = newId;

    }

 

    /**

     * 获得名称.

     * @return 名称

     */

    public String getName() {

        return name;

    }

 

    /**

     * 设置名称.

     * @param newName 名称

     */

    public void setName(String newName) {

        this.name = newName;

    }

}

例7.14

    我们来写senduser.html,在页面上填写传递的参数并传到显示用JSP中,代码如例7.15所示。

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>使用UserBean_传递参数</title>

</head>

<body>

<form name="main" action="user.jsp" method="post">

    编号:<input type="text" name="id"/>

    <br>

    姓名:<input type="text" name="name"/>

    <br>

    <input type="submit" value="传送参数"/>

</form>

</body>

</html>

例7.15

    好了,我们先用第一种方法来写user.jsp来显示传递的参数,即用如下语法:

<jsp:setProperty   name=” beanNm” property=”*” />

代码如例7.16所示。

 

 

<%@ page language="java" contentType="text/html; charset=UTF-8"

      pageEncoding="UTF-8"%>

<html>

<head>

<title>使用UserBean_显示参数</title>

</head>

<body>

<%

    // 设置获得参数用的编码

      request.setCharacterEncoding("UTF-8");

%>

<jsp:useBean id="userBean" class="com.jy.sample.javabean.UserBean" scope="page"/>

<!-- 通过自省机制设置属性 -->

<jsp:setProperty property="*" name="userBean"/>

<!-- 显示属性值 -->

编号:<jsp:getProperty name="userBean" property="id"/>

<br>

名称:<jsp:getProperty name="userBean" property="name"/>

</body>

</html>

例7.16

    我们来运行senduser.html,执行结果如图7.10所示。

 

图7.10

    我们在编号中输入“1”,在姓名栏输入“张三”。点击传送参数按钮,将看到如图7.11所示的页面,证明,我们的参数正常设置到UserBean中了。

 

图7.11

    下面我们通过修改例7.16的代码来实现第二种设置属性的方法,即如下语法:

<jsp:setProperty   name=” beanNm” property=”propertyNm” />

如果我们把例7.16的灰色阴影部分

<!-- 通过自省机制设置属性 -->

<jsp:setProperty property="*" name="userBean"/>

更换成如下代码:

<!-- 通过自省机制设置属性 -->

<jsp:setProperty property="id" name="userBean"/>

<jsp:setProperty property="name" name="userBean"/>

    这样执行得到的结果和使用第一种方法的结果一样。但是第二种方法让用户能够有弹性地设定JavaBeande属性值。我们有id和name两个属性,如果我们只设定name属性的话,即只有如下语句:

<!-- 通过自省机制设置属性 -->

<jsp:setProperty property="name" name="userBean"/>

    则执行结果如图7.12所示。

 

图7.12

    现在我们来看看第三种方法,即使用如下语法:

<jsp:setProperty   name="beanNm" property="propertyNm" param="paramNm"/>

    这种方法,比前边的方法灵活性要大,因为前边的两种方法有一个限制,那就是窗体的参数名称和JavaBean的属性名称必须要大小写一致才能顺利使用。如果两者名称不相同,就不能够设定JavaBean的属性值,这是可以用第三种方式来达到。

    首先我们把senduser.html中的两个输入框的代码修改如下:

    编号:<input type="text" name="myid"/>

    <br>

    姓名:<input type="text" name="myname"/>

      <br>

    即编号的name属性由id改为了myid;姓名的name属性由name改为了myname。这样,这两个参数的属性就和JavaBean中的id和name不一样了。

    我们再来修改user.jsp的设置属性的方法,把<jsp:setProperty>修改成如下格式:

<!-- 通过自省机制设置属性 -->

<jsp:setProperty property="id" param="myid" name="userBean"/>

<jsp:setProperty property="name" param="myname" name="userBean"/>

    来执行senduser.html,当我们输入编号“1”,姓名“张三”并点击传送参数按钮后,执行结果如图7.13所示。

 

 

图7.13

    最后,我们来看看最后一种设置JavaBean属性的方法,即

<jsp:setProperty   name=" beanNm" property="propertyNm" value="val"   />

    这是最灵活的方式,前边三种方法都是将窗体中参数的值设定到JavaBean的属性之中,而这种方法可以让用户动态设定JavaBean属性的值,我们把user.jsp的代码修改如例7.17所示。

<%@ page language="java" contentType="text/html;   charset=UTF-8"

      pageEncoding="UTF-8"%>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>使用UserBean_显示参数</title>

</head>

<body>

<%

    // 设置获得参数用的编码

    request.setCharacterEncoding("UTF-8");

    // 设置参数

    Long newid = new Long(5);

%>

<jsp:useBean id="userBean" class="com.jy.sample.javabean.UserBean" scope="page"/>

<!-- 通过自省机制设置属性 -->

<jsp:setProperty property="id" value="<%=newid%>" name="userBean"/>

<jsp:setProperty property="name" value="<%=request.getParameter(\"myname\")%>" name="userBean"/>

<!-- 显示属性值 -->

编号:<jsp:getProperty name="userBean" property="id"/>

<br>

名称:<jsp:getProperty name="userBean" property="name"/>

</body>

</html>

例7.17

    当我们在senduser.html中设定编号“1”和名称“张三”并点击传送参数按钮后,执行结果如图7.14。

 

图7.14

    由于我们在user.jsp中设定编号为5,而不是senduser.html中设定的“1”,所以表示出来的编号是“5”。

    对于前三种设定的方法,窗体传递的数据类型都是String类型,如果JavaBean的类型不是String而是其他的什么,就需要用到JSP页面提供的类型自动转换功能,系统功过简单类型的valueOf()方法来进行类型转换,但是不能转换复杂类型,对于复杂类型,需要用户自己来实现。

注意:对于第四种设置方法,如果传递参数和JavaBean中属性的类型不一致的话,如果要使用<%=request.getParameter()%>方式来设值,将会出现错误,是由于通过<%=request.getParameter()%>获得的参数一定是String,如果JavaBean中的属性类型不是String,就会报错,这种情况需要用户自己转换类型。

7.4  总结

  • JavaBean是一种可重用组件。通过<jsp:useBean>来声明。
  • <jsp:setProperty>和<jsp:getProperty>都是存取JavaBean属性值。
  • <jsp:include>动作用于将任何内容或文件嵌入到JSP页面。
  • <jsp:forward>动作用于将请求转发给其他JSP页面。

转载于:https://www.cnblogs.com/Aha-Best/p/10883219.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值