第5课
将JavaBeans技术添加到Mix中

[<<返回] [目录] [下一个>>]

我们可以利用JavaBeans技术将JavaBean置入JSP页面和CalcBean session bean之间,以获得一个更佳的模型、视图、控制器(MVC)划分。MVC是 一个包含有三种对象的设计模式。这个模型提供了应用业务逻辑,View(视图)是 它的屏幕显示,Controller(控制器)是一个管理用户与View交互的对象。所谓 设计模式就是描述一个经常发生的问题的解决方案,对于问题的每次出现,相应 的解决方案都不尽相同。

第4课建立“JavaServer Pages技术” 的目的就是使HTML和JSP页面能够提供屏幕显示(View),并管理用户与数据之间 的交互(Controller)。 entity和session bean( BonusBeanCalcBean)是应用对象或模型。

这一课采用了JSP页面作为屏幕显示(View), 采用JavaBean管理用户与View 之间的交互(Controller), 采用entity和session beans作为应用对象(模型) 。 像这样将Controller 与View分开,使JavaBean作为session bean的一个包装, 同时为我们的范例体现了一个清晰得多的MVC划分。使用此种清晰设计模式的应用 更加容易更新、维护和管理。

关于范例

创建bonus.jsp

创建JavaBeans类

Bean属性

移除WAR文件

创建新WAR文件

验证和部署J2EE应用

运行J2EE应用

更多信息

关于本范例

在第4课(JavaServer Pages技术)中, 应用用户界面由带有一个HTML表单的HTML页面组成。当用户在HTML页面上点击 “提交”按钮时,HTML表单就会调用JSP页面。

创建用户界面的另一种方式是使用一个JSP页面,它包括HTML表单、 JSPscriplet和JSP-SPECIFIC标签,用来同JavaBean相互作用。当加载JSP页面时, HTML表单就会被显示,同时,scriplet和用来同JavaBean相互作用的 JSP-Specific标签也会被执行。由于还没有提供数据,因此,界面的外观如 图17所示。

 

Bonus Calculation
图17 : 当加载 bonus.jsp

在用户输入一些数据并点击“提交”按钮后,HTML表单会重新显示,用于 scriplet和与JavaBean相互作用的JSP-Specific标签会重新被执行。此时,数据 已经被提交。如图18所示。这是因为 bonus.jsp上的HTML表单的ACTION 参数被递归调用的结果。Bonus Calculation

 

图18 : 用户输入数据并点击“提交 ”按钮后

如果用户输入的社会安全号码相同,会收到一个显示在JSP页面上的重复关键 字错误提示信息,如图19所示。

 

Bonus Calculation
图19 : 重复关键字错误

创建bonus.jsp

bonus.jsp 的代码很清楚,因为用来查找session bean并计算bonus的代码在JavaBean中。该文件的第一部分包含用来创建表单的 HTML代码。 文件中的第二部分是用来将HTML表单数据传递给JavaBean的代码。以 下便是完整的bonus.jsp文件。在讨论它的scriplet和 用来同JavaBean相互作用的JSP-Specific标签之前,应仔细查看这个文件。

<HTML>
<BODY BGCOLOR = "WHITE">
<HEAD>
<TITLE>Bonus Calculation</TITLE>
</HEAD>

<BLOCKQUOTE>
<H3>Bonus Calculation</H3>

<!--ACTION parameter calls this page-->
<FORM METHOD="GET" ACTION="bonus.jsp">

<P>
Enter social security Number:
<P>
<INPUT TYPE="TEXT" NAME="SOCSEC"></INPUT>
<P>

Enter Multiplier:
<P>
<INPUT TYPE="TEXT" NAME="MULTIPLIER"></INPUT>

<P>
<INPUT TYPE="SUBMIT" VALUE="Submit">
<INPUT TYPE="RESET">
</FORM>

<!--Scriptlet and JavaBeans Tags start here -->
<jsp:useBean id = "jbonus" class = "JBonusBean"/>

<%! String sMult, ssec; %>
<%
sMult = request.getParameter("MULTIPLIER");
ssec = request.getParameter("SOCSEC");
%>

<jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/>
<jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/>

Social security number retrieved:
<jsp:getProperty name="jbonus" property="socsec"/>

<P>
Bonus Amount retrieved:
<jsp:getProperty name="jbonus" property="bonusAmt"/>

<P>
Error messages:
<jsp:getProperty name = "jbonus" property="message"/>

</BLOCKQUOTE>

</BODY>
</HTML>

指定JavaBean

下面的HTML 标签指定了本范例中所使用的JavaBean。 参数id 为该JavaBean定义了一个用来引用它的别名,参数class 指明了JavaBean的类。在本范例中,idjbonusclassJBonusBean

<jsp:useBean id = "jbonus" class = "JBonusBean"/>

获得数据

下面的JSPscriplet从HTML表单填写域中检索用户所填写的数据。乘数存储在 sMult String变量中,社会安全号码存储在 ssec String变量中。

<%! String sMult, ssec; %>
<%
sMult = request.getParameter("MULTIPLIER");
ssec = request.getParameter("SOCSEC");
%>

将数据传递给JavaBean

下面的HTML标签在JavaBean中设置了两个属性。 一个属性是JavaBean类中的 私有域。第一行使用了jsp:setProperty名称标签,用 来把JBonusBean类(别名为jbonus id)中的strMult域设置为存储于sMult 变量中的值。第二行是对JBonusBean类中的 socsec域执行相似的操作。

<jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/>
<jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/>

The value="<%=ssec%>" expression sends the data contained in the ssec variable to the socsec field in the JavaBean.

从JavaBean中检索数据

从JavaBean中检索数据同将数据发送给JavaBean的过程相似。可以使用 jsp:getProperty名称标签,表明你想获得的数据的属 性(私有域)。下面的getProperty名称标签用来检索 存储在JBonusBean类中的 socsec私有域中的数据。(用 jbonus.id别名)。

Social security number retrieved:
<jsp:getProperty name="jbonus" property="socsec"/>

下面的标签对JBonusBean类中的 bonusAmtmessage域执行 类似的操作。

<P>
Bonus Amount retrieved:
<jsp:getProperty name="jbonus" property="bonusAmt"/>

<P>
Error messages:
<jsp:getProperty name = "jbonus" property="message"/>

创建JavaBeans类

JavaBeanTM类(或简称为bean) 看起来就像普通的JavaTM编程语言类。 但是 对于一个bean来说,JavaBean类必须遵循一套简单的命名和设计规范,正如 JavaBean规范中所规定的。因为bean遵循JavaBeans规范,因此,可以通过采用同 样这些规范的其它程序和工具来存取和管理这些bean。

在“创建bonus.jsp”一节中,HTML标签 和JSPscriplet用来获得和设置JBonusBean类的私有域 中的数据。 之所以能够这样做是因为JBonusBean类遵 循了JavaBean的命名和设计规范。

这一节将对JBonusBean代码进行介绍,并简单介绍 一下JavaBeans同JSP页面的一起使用时的技术。可进入以下网址获得有关 JavaBeans技术的进一步信息: http://java.sun.com/beans/index.html

下面是完整的JBonusBean类。之后是对其相关部分 的讨论。

import javax.naming.*;
import javax.rmi.PortableRemoteObject;
import Beans.*;

public class JBonusBean {
  private String strMult, socsec, message;
  private double bonusAmt;
  CalcHome homecalc;

  public JBonusBean() {
    try{
      InitialContext ctx = new InitialContext();
      Object objref = ctx.lookup("calcs");
      homecalc = (CalcHome)
         PortableRemoteObject.narrow(
            objref, CalcHome.class);
    } catch (javax.naming.NamingException e) {
      e.printStackTrace();
    }
  }
  public double getBonusAmt() {
    if(strMult != null){
      Integer integerMult = new Integer(strMult);
      int multiplier = integerMult.intValue();
      try {
        double bonus = 100.00;
        Calc theCalculation = homecalc.create();
        Bonus theBonus = theCalculation.calcBonus(
           multiplier, bonus, socsec);
        Bonus record = theCalculation.getRecord(
            socsec);
        bonusAmt = record.getBonus();
        socsec = record.getSocSec();
      } catch (javax.ejb.DuplicateKeyException e) {
        message = e.getMessage();
      } catch (javax.ejb.CreateException e) {
        e.printStackTrace();
      } catch (java.rmi.RemoteException e) {
        e.printStackTrace();
      }
      return this.bonusAmt;
    } else {
      this.bonusAmt = 0;
      this.message = "None.";
      return this.bonusAmt;
    }
  }

  public String getMessage(){
    return this.message;
  }
  public String getSocsec(){
    return this.socsec;
  }
  public String getStrMult(){
    return this.strMult;
  }
  public void setSocsec(String socsec) {
   this.socsec = socsec;
  }
  public void setStrMult(String strMult) {
   this.strMult = strMult;
  }
}

Bean 属性

这里的属性定义了对JavaBean来说,其它程序和工具通过get和set方法能够对 哪些数据进行访问。这些数据可用来定义JavaBeans的外观和行为,或用于一系列 计算的结果中。属性应该是私有的类域,只有通过get和set方法才能访问。

下面的代码段表明了JBonusBean类的私有属性。 JBonusBean类对于每个域都一个对应的 get方法,对于 strMultsocsec域有对应 的set<property>方法。

public class JBonusBean {
private String strMult, socsec, message;
private double bonusAmt;

构造函数

JBonusBean构造函数查找session Bean。

public JBonusBean() {
try{
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
homecalc = (CalcHome)
PortableRemoteObject.narrow(
objref, CalcHome.class);
} catch (javax.naming.NamingException e) {
e.printStackTrace();
}
}

Set方法

JBonusBean有两个setter方法(带set 前缀的方法)。Setter方法将属性(私有域)设置为指定的值。两个setter方法 分别是setSocsec和setStrMult ,用来设置 socsec和strMult私有域(JavaBean属性)

在这个范例中,用来设置socsecstrMult 属性的值来自JSP页面的setProperty name 标签。 J2EE服务器使用以下setProperty name 标签中所提供 的信息,来定位JbonusBean(别名为 jbonus id)中的对应的设置方法。

<jsp:setProperty name = "jbonus" property="strMult" value="<%=sMult%>"/>
<jsp:setProperty name = "jbonus" property="socsec" value="<%=ssec%>"/>

JBonusBean类中,setset<property> 方法遵循了命名规范,因此,使J2EE服务器能够把JSP文件中的setProperty name 标签映射到正确的set<property>方法,并将数 据从JSP页面传递给JavaBean。

setter方法的名称由单词set和属性名称组成。这 个属性名称是JBonusBean私有域的一个名称。但是域 名称的第一个字母为通常为小写,而方法名称的第二个词则经常为大写。因此, 为了设置socsecsetSocsec。 J2EE服务器使方法名称的大写的SSocsecsocsec 域的小写相互映射。Setter方法没有返回值,但有一个类型合适的参数。

public void setSocsec(String socsec) {
this.socsec = socsec;
}
public void setStrMult(String strMult) {
this.strMult = strMult;
}

Get方法

JBonusBean 有四个getter方法(带get 前缀的方法)。Getter方法获取和返回属性值(私有域值)。 四个getter方法为 getBonusAmtgetMessage, getSocsecgetStrMult, 分别从bonusAmt, Message, SocsecstrMult私有域中 返回数据(JavaBean属性)。

在这个范例中,用来设置bonusAmtmessage 栏的值来自getBonusAmt方法。JSP页面利用以下的 getProperty name标签从JBonusBeanstrMult栏),但这个值并不被JSP页面所检索。

Social security number retrieved:
<jsp:getProperty name="jbonus" property="socsec"/>

<P>
Bonus Amount retrieved:
<jsp:getProperty name="jbonus" property="bonusAmt"/>

<P>
Error messages:
<jsp:getProperty name = "jbonus" property="message"/>

Getter方法同setter方法遵循着相同的规范,因此,JSP页面可以从JBonusBean 中检索数据。getter方法通常有一个返回值,但没有参数。你会注意到,虽然在 这个范例中getBonusAmt方法设置属性值并且不需要有 一个返回值,但它还是返回了this.bonusAmt,以避免 J2EE运行时(runtime)服务器错误。

在没有strMult值提交时,getBonusAmt 方法会使用一个if-else语句来进行处理。当JSP页面第 一次被下载时,终端用户还没有提交任何数据,但页面上的所有标签和scriplet 都已经运行。这时,传递给JBonusBeanstrMult 属性的数据值为零,这样就会导致一个零乘数和一个零bonusAmt 值。当JSP页面获取或将要显示这个零bonusAmt值时, 就会出现一个运行时服务器错误。为了避免这个运行错误的发生,在收到来自JSP 页面的零strMult值时,bonusAmt 被设置为0。

public double getBonusAmt() {
if(strMult != null){
Integer integerMult = new Integer(strMult);
int multiplier = integerMult.intValue();
try {
double bonus = 100.00;
Calc theCalculation = homecalc.create();
Bonus theBonus = theCalculation.calcBonus(
multiplier, bonus, socsec);
Bonus record = theCalculation.getRecord(
socsec);
bonusAmt = record.getBonus();
socsec = record.getSocSec();
} catch (javax.ejb.DuplicateKeyException e) {
message = e.getMessage();
} catch (javax.ejb.CreateException e) {
e.printStackTrace();
} catch (java.rmi.RemoteException e) {
e.printStackTrace();
}
return this.bonusAmt;
} else {
this.bonusAmt = 0;
this.message = "None.";
return this.bonusAmt;
}
}
public String getMessage(){
return this.message;
}
public String getSocsec(){
return this.socsec;
}
public String getStrMult(){
return this.strMult;
}
public void setSocsec(String socsec) {
this.socsec = socsec;
}
public void setStrMult(String strMult) {
this.strMult = strMult;
}

启动平台和工具

在运行这个范例之前,需要启动J2EE服务器、部署工具和Cloudscape数据库。 在不同的窗口中,键入以下命令:

j2ee -verbose
deploytool
cloudscape -start

如果不起作用,则从J2EE目录中键入。

Unix

j2sdkee1.2.1/bin/j2ee -verbose
j2sdkee1.2.1/bin/deploytool
j2sdkee1.2.1/bin/cloudscape -start

Windows

j2sdkee1.2.1\bin\j2ee -verbose
j2sdkee1.2.1\bin\deploytool
j2sdkee1.2.1\bin\cloudscape -start

移除WAR文件

由于需要为应用添加一个全新的类,你必须将前一课的WAR文件删除,创建一 个新的WAR文件。

本地应用:

  • 点击2BeansApp图标,以便能够看到它的应用 组件。
  • 选择BonusWar
  • 从编辑菜单中选择“删除”。

创建新WAR文件

文件菜单:

选择“新Web 组件”。

介绍 :

阅读后点击“下一步”。

WAR文件一般属性:

  • 指明BonusWar为显示名称。
  • 点击“添加”
  • 在下一个窗口中,进入ClientCode目录,添加 bonus.jsp
  • 点击“下一步”,进入ClientCode目录,添加 JBonusBean.class
  • 点击“完成”。
注:应在添加JBonusBean.class之前 添加bonus.jsp

WAR文件一般属性:

  • 点击“下一步”。

选择组件类别:

  • 使Bonus.jsp作为JSP文件名。
  • 选定Describe a JSP
  • 点击“下一步”。

组件一般属性:

  • 使BonusJSP为JSP文件名。
  • 点击“完成”。

检查窗口:

  • 选择Web Context。
  • 指定JSPRoot

验证和部署J2EE应用

在部署应用之前最好能够运行验证器。验证器将挑出应用组件中的错误,如编 译器未曾捕获的丢失的enterprise bean方法。

验证:

  • 选定2BeansApp, 从“工具”菜单中选择“验 证器”。
  • 在弹出的对话框中,点击“ OK”。 窗口将通 知你测试成功。前提是使用了本课中所提供的session bean代码。
  • 关闭验证器窗口,准备部署应用。
注: 在Version 1.2.1软件中,你可能会得到一个 tests app.WebURI 的错误。这表明,在WAR文件创建过程中,部署工具没 有将.war扩展名附加给WAR 文件。 这是一个小的错误,不影响J2EE应用的部署。

部署:

  • 从“工具”菜单中选择“部署应用”。 会弹出一个“部署BonusApp” 对话框。
  • 验证“目标服务器”选项或者是本地主机或是运行J2EE服务器的主机的名 称。

    注:不要选择“Return Client Jar”选项。只有在为客户程序部署 独立的应用时才选择这个选项。本实例使用了一个servlet和HTML页面,因此,不 应该选择这个选项。否则会生成一个带有独立式应用所需部署信息的JAR文件。


  • 点击“下一步”。 确定CalcBean的JNDI名称为 calcsBonusBean的 JNDI名称为bonus。 如果不是,则需要将JNDI名称 键入,然后按下回车键。
  • 点击“下一步”。 确定“上下文目录”名称显示为JSPRoot。 如果不是,则需要将其键入,然后按下回车键。
  • 点击“下一步”。
  • 点击“完成”开始部署。此时,会弹出一个显示部署操作状态的对话框。
  • 完成后,左侧的三个状态条都将阴影化,如 图20所示。点击“OK”。

 

Deployment Progress
图20 : 部署应用

运行J2EE应用

web 服务器的运行端口默认为8000。 若要打开bonus.jsp 页面,可进入以下地址, http://localhost:8000/BonusRoot/bonus.html, 这是部署工具放置HTML文件的位置。

  • 填入社会安全号码和乘数。
  • 点击“提交”按钮。Bonus.jsp会对传入的数据 进行处理,并返回一个带bonus计算值的HTML页面。

可以对范例进行屏幕定格(screen capture)来显示程序运转时状态。

多信息

访问JavaBeans的主页,http://java.sun.com/beans/index.html, 了解有关JavaBeans技术的更多信息。

[TOP]

 

常见问答
下载中心
产品简介
 
 
Solaris论坛
 
   
 
null