|
第5课
将JavaBeans技术添加到Mix中
[<<返回]
[目录]
[下一个>>]
我们可以利用JavaBeans技术将JavaBean置入JSP页面和CalcBean
session bean之间,以获得一个更佳的模型、视图、控制器(MVC)划分。MVC是 一个包含有三种对象的设计模式。这个模型提供了应用业务逻辑,View(视图)是
它的屏幕显示,Controller(控制器)是一个管理用户与View交互的对象。所谓 设计模式就是描述一个经常发生的问题的解决方案,对于问题的每次出现,相应
的解决方案都不尽相同。
第4课建立“JavaServer
Pages技术” 的目的就是使HTML和JSP页面能够提供屏幕显示(View),并管理用户与数据之间 的交互(Controller)。
entity和session bean( BonusBean 和CalcBean)是应用对象或模型。
这一课采用了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所示。
在用户输入一些数据并点击“提交”按钮后,HTML表单会重新显示,用于 scriplet和与JavaBean相互作用的JSP-Specific标签会重新被执行。此时,数据
已经被提交。如图18所示。这是因为 bonus.jsp上的HTML表单的ACTION
参数被递归调用的结果。
如果用户输入的社会安全号码相同,会收到一个显示在JSP页面上的重复关键 字错误提示信息,如图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的类。在本范例中,id为jbonus,
class为JBonusBean。
<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类中的
bonusAmt和message域执行
类似的操作。
<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方法,对于
strMult和socsec域有对应
的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属性)。
在这个范例中,用来设置socsec和strMult
属性的值来自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服务器使方法名称的大写的SSocsec与socsec
域的小写相互映射。Setter方法没有返回值,但有一个类型合适的参数。
public void setSocsec(String socsec) {
this.socsec = socsec;
}
public void setStrMult(String strMult) {
this.strMult = strMult;
}
Get方法
JBonusBean 有四个getter方法(带get
前缀的方法)。Getter方法获取和返回属性值(私有域值)。 四个getter方法为 getBonusAmt,getMessage,
getSocsec和getStrMult,
分别从bonusAmt, Message,
Socsec和strMult私有域中
返回数据(JavaBean属性)。
在这个范例中,用来设置bonusAmt和message
栏的值来自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
都已经运行。这时,传递给JBonusBean的strMult
属性的数据值为零,这样就会导致一个零乘数和一个零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名称为 calcs,BonusBean的
JNDI名称为bonus。 如果不是,则需要将JNDI名称 键入,然后按下回车键。
- 点击“下一步”。 确定“上下文目录”名称显示为
JSPRoot。 如果不是,则需要将其键入,然后按下回车键。
- 点击“下一步”。
- 点击“完成”开始部署。此时,会弹出一个显示部署操作状态的对话框。
- 完成后,左侧的三个状态条都将阴影化,如 图20所示。点击“
OK”。
运行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]
|