开发实体Bean的目的是管理数据的持久性,通过实体Bean的接口客户端可以访问数据资源,对于一定结构的数据,可以通过一些方式来加强提取数据的能力。本节介绍利用值对象和XML传递数据的方式。
值对象是实现了Java可序列化接口的类,可以利用它在实体Bean内部实现数据提取的方法。值对象本身保存着实体Bean的一些字段,并且为这些字段提供了get()和set()方法,例如下面的NodeBook:
public class NodeBook implements java.io.Serializable {
private String title;
private String text;
private Date date;
public Date getDate() {
return date;
}
public String getText() {
return text;
}
public String getTitle() {
return title;
}
public void setDate(Date date) {
this.date = date;
}
public void setText(String string) {
text = string;
}
public void setTitle(String string) {
title = string;
}
}
通过在实体Bean与客户端之间传递NodeBook对象,可以一次性得到客户端想要的数据。实现传递值对象的方法,需要在实体Bean实现类内部提供,并且在实体Bean的主接口或者本地主接口中发布这一方法。
以本地接口为例,在本地主接口中添加getNodeBook方法:
public NodeBook getNodeBook(String title) ;
这个方法需要在实体Bean实现类中实现,并以相对应的名称命名,即实体Bean实现类的方法名比主接口中的方法多了一个ejbHome- 前缀:
/**
*
* @ejb.home-method view-type = "local"
*/
public NodeBook ejbHomeGetNodeBook(String title){
NodeLocalHome home = (NodeLocalHome) ctx.getEJBLocalHome();
NodeBook nbook = new NodeBook();
try {
if(!home.findByTitle(title).isEmpty()){
NodeLocal node = home.findByPrimaryKey(title);
nbook.setTitle(title);
nbook.setText(node.getText());
nbook.setDate(node.getDate());
}
} catch (FinderException e) {
e.printStackTrace();
}
return nbook;
}
方法前面的XDoclet标记部分,可以使XDoclet任务在生成本地主接口代码时,生成对应于这个方法的本地主接口方法GetNodeBook,而省去了自己修改本地主接口的工作。
实体Bean实现类的ejbHomeGetNodeBook方法对外以NodeBook对象来传递数据,简化了客户端的操作。此时的实体Bean客户端可以通过下面的方法从实体Bean得到数据:
...
NodeBook nBook = home.getNodeBook(title);
out.println("<table><tr><td>"+nBook.getTitle()+"</td></tr></br>");
out.println("<tr><td>"+nBook.getText()+"</td></tr>");
out.println("<tr><td>"+nBook.getDate()+"</td></tr></table>"
从修改NodeBean的示例中可以看到,通过值对象可以很有效地传递数据,但是对于Web表现层来说,仍然需要值对象的方法,因此当值对象改变,或者实体Bean管理的数据改变时,Web层的Servlet也要作相应的改变。下面介绍进一步的数据传递的方式,即通过XML来传递数据。
前面介绍的值对象传递方式是利用可序列化的对象作为数据的载体,本节介绍利用XML来传递数据的方式。这种方式与值对象的不同之处在于数据的结构是记录在XML之中的,客户端可以直接利用XML的编程接口处理得到的数据。
在这里为NodeBean添加一个GetXML()方法,这个方法检索所有在此之前存入的数据,并以XML形式返回。
在本地主接口中添加接口方法:
public String getXML() ;
方法返回的代表NodeBook的XML数据如下:
<?xml version="1.0" encoding="GB2312"?>
<node xmlns="http://com.liuyang.ejb.cmp.node">
<title>this is a title</title>
<text>this is some words for text test</text>
<date>2003-12-16T01:30:48.250+08:00</date>
</node>
为了提供可靠的XML数据,在实体Bean实现类中实现这个方法时,在这里可利用Castor提供的XML数据绑定API,其中一些内容可以参见本书第6章。
首先定义XML数据的Schema:
<?xml version="1.0" encoding="gb2312"?>
<schema targetNamespace="http://com.liuyang.ejb.cmp.node"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:NodeBook="http://com.liuyang.ejb.cmp.node">
<element name="NodeBook">
<complexType>
<sequence>
<element name="title" type="string"/>
<element name="text" type="string"/>
<element name="date" type="dateTime"/>
</sequence>
</complexType>
</element>
</schema>
创建Schema的一个好处是可以在生成XML数据时得以验证,并且通过数据绑定可以很容易地实现Java对象和XML数据之间的编组和解组。
利用Castor从Schema生成源代码的工具,重新生成NodeBook:
SourceGenerator sg = new SourceGenerator();
sg.generateSource("NodeBook.xsd","com.liuyang.ejb.cmp.node.data");
这样在实体Bean的实现方法中就可以利用数据绑定从NodeBook直接得到XML数据:
/**
*
* @ejb.home-method view-type = "local"
*/
public String ejbHomeGetXML(){
...
StringWriter wr = new StringWriter();
Marshaller marshaller = new Marshaller(wr);
marshaller.marshal(nBook);
...
}
在NodeBean得到XML数据之后,可以利用XSLT技术转换为HTML,直接显示到客户端的浏览器,如图3-12所示。

图3-12 利用XML实现的Web界面
设计不同的XSL可以改变XML数据的表现形式,从这个示例可以看到,利用XML作为数据的接口,可以使组件之间的关系变得更为友好。 |