﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-sdkdsyy</title><link>http://www.blogjava.net/sdkdsyy/</link><description /><language>zh-cn</language><lastBuildDate>Wed, 29 Apr 2026 03:25:05 GMT</lastBuildDate><pubDate>Wed, 29 Apr 2026 03:25:05 GMT</pubDate><ttl>60</ttl><item><title>什么是j2ee【转】</title><link>http://www.blogjava.net/sdkdsyy/archive/2007/03/16/104347.html</link><dc:creator>寿业勇</dc:creator><author>寿业勇</author><pubDate>Fri, 16 Mar 2007 12:13:00 GMT</pubDate><guid>http://www.blogjava.net/sdkdsyy/archive/2007/03/16/104347.html</guid><wfw:comment>http://www.blogjava.net/sdkdsyy/comments/104347.html</wfw:comment><comments>http://www.blogjava.net/sdkdsyy/archive/2007/03/16/104347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sdkdsyy/comments/commentRss/104347.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdkdsyy/services/trackbacks/104347.html</trackback:ping><description><![CDATA[
		<font color="#000000" size="2">J2EE: 电子商务和信息技术的快速发展以及对它们的需求给应用程序开发人员带来了新的压力。<br />必须以比以前更少的金钱、更少的资源来更快地设计、开发企业应用程序。为了降低成本，并加快企业应用程序的设计和开发， J2EE 平台提供了一个基于组件的方法，来设计、开发、装配及部署企业应用程序。J2EE 平台提供了多层的分布式的应用模型、组件再用、一致化的安全模型以及灵活的事务控制。您不仅可以用比以前更快的速度向市场推出创造性的客户解决方案，而且您的平台独立的、基于组件的J2EE 解决方案不会被束缚在任何一个厂商的产品和API 上。<br />1. J2EE 规范定义了以下种类的组件<br />• 应用客户组件。<br />• Enterprise JavaBeans 组件。<br />• S e r v l e t及JavaServer Pages（JSP 页面）组件（也被称作Web 组件）。<br />• Applet。<br />一个多层的分布式的应用模型意味着应用逻辑被根据功能划分成组件，并且可以在同一个<br />服务器或不同的服务器上安装组成J2EE 应用的这些不同的组件。一个应用组件应被安装在什么<br />地方，取决于该应用组件属于该多层的J2EE 环境中的哪一层。这些层是客户层、We b层、业务<br />层及企业信息系统层（ EIS ）等。<br />(1) 客户层<br />J2EE 应用可以是基于Web 的，也可以是不基于Web 的。在一个基于Web 的J2EE 应用中，用户的浏览器在客户层中运行，并从一个We b服务器下载Web 层中的静态HTML 页面或由J S P或Servlet 生成的动态HTML 页面。在一个不基于Web 的J2EE 应用程序中，一个独立客户程序不运行在一个HTML 页面中，而是运行在其他一些基于网络的系统（比如手持设备或汽车电话）中，Applet 程序，在客户层中运行，并在不经过Web 层的情况下访问Enterprise Beans。这个不基于Web 的客户层可能也包括一个JavaBeans 类来管理用户输入，并将该输入发送到在企业层中运行的Enterprise Beans类来进行处理。根据J2EE 规范，JavaBeans 类不被视为组件。为J2EE 平台编写的JavaBeans 类有实例变量和用于访问实例变量中的数据的“ get 和set 方法”。以这种方式使用的JavaBeans 类在设计和实现上通常都是简单的，但是它们必须符合JavaBeans 规范中列出的命名和设计约定。<br />(2) Web 层<br />        J2EE Web 组件可以由JSP 页面、基于Web 的A p p l e t以及显示HTML 页面的S e r v l e t组成。调用S e r v l e t或者JSP 页面的HTML 页面在应用程序组装时与Web 组件打包在一起。就像客户层一样，Web 层可能包括一个JavaBeans 类来管理用户输入，并将输入发送到在业务层中运行的Enterprise Beans 类来进行处理。运行在客户层的Web 组件依赖容器来支持诸如客户请求和响应及Enterprise Bean 查询等。<br />(3) 业务层<br />        作为解决或满足某个特定业务领域（比如银行、零售或金融业）需要的逻辑的业务代码由运行在业务层的Enterprise Beans 来执行。一个Enterprise Bean 从客户程序处接收数据，对数据进行处理（如果需要），再将数据发送到企业信息系统层存储起来。一个Enterprise Beans 还从存储中检索数据，并将数据送回客户程序。运行在业务层的Enterprise Beans 依赖于容器来为诸如事务、生命期、状态管理、多线程及资源存储池等提供通常都非常复杂的系统级代码。业务层经常被称作Enterprise JavaBeans （EJB ）层。业务层和Web 层一起构成了3 层J 2 E E应用的中间层，而其他两层是客户层和企业信息系统层。<br />(4) 企业信息系统层<br />企业信息系统层运行企业信息系统软件，这层包括企业基础设施系统，例如企业资源计划（E R P）、大型机事务处理（ mainframe transactionprocessing ）、数据库系统及其他遗留信息系统（legacy informationsystems ）。J2EE 应用组件因为某种原因( 例如访问数据库) 可能需要访问企业信息系统。J2EE 平台的未来版本将支持Connector 架构，该架构是将J2EE 平台连接到企业信息系统上的一个标准A P I。<br />(5) 查询服务<br />因为一个J2EE 应用程序的组件是单独运行的，并且往往在不同的设备上运行，因此，需要一种能让客户层和Web 层代码查询并引用其他代码和资源的方法。客户层和Web 层代码使用Java 命名和目录接口（JNDI ）来查询用户定义的对象（例如Enterprise Beans ）、环境条目（例如一个数据库驱动器的位置）、企业信息系统层中用于查找资源的JDBC DataSource对象，以及消息连接。<br />(6) 安全和事务管理<br />诸如安全和事务管理这样的应用行为可以在部署时在Web 和Enterprise Beans 组件上进行配置。这个特征将应用逻辑从可能随装配而变化的配置设定中分开了。J2EE 安全模型允许配置一个Web 或Enterprise Beans 组件，使系统资源只能由授权的用户访问。例如，一个Web 组件可以被配置成提示输入用户名和密码。一个Enterprise Beans 组件可以被配置成只让特定团体中的成员调用其某些方法。或者，一个Servlet 组件可以被配置成让某个组织中的所有人都能访问其某些方法，同时只让该组织中的某些享有特权的人访问其中一些方法。同样是该Servlet 组件，可以针对另外一个环境而被配置成让每个人都能访问其所有方法，或者仅让选定的少数人访问其所有方法。<br />        J2EE 事务模型使得能够在部署时定义构成一个单一事务的方法之间的关系，以使一个事务中的所有方法被处理成一个单一的单元。这是我们所希望的，因为一个事务是一系列步骤，这些步骤要么全部完成，要么全部取消。例如，一个Enterprise Beans 可能有一组方法，使我们可以通过从第一个账户借出并存入第二个账户的方式而将钱从第一个账户转移到第二个账户。我们希望全部的操作被作为一个单元对待，这样，如果在借出之后存入之前发生了故障，该借出操作被取消。事务属性是在装配期间定义在一个组件上的。这使得能将来自多个应用组件的方法归到一个事务中，这说明，我们可以轻易变更一个J2EE 应用程序中的应用组件，并重新指定事务属性，而不必改变代码或重新编译。在设计应用组件时，要记住，尽管Enterprise Beans 有一个可使应用组件的容器自动启动多步事务的机制，但是Applet 和应用的客户容器可能并不支持这一点。然而， Applet 和应用客户容器总是能够调用支持这一点的一个Enterprise Beans。还应当注意， JSP 页面和Servlet 没有被设计成是事务的，它们通常应当将事务工作交给一个Enterprise Bean 来完成。然而，如果事务工作在一个JSP 页面或Servlet 中是必须的，那么此种工作也应当是非常有限的。<br />(7) 可重用应用组件<br />J2EE 组件（Applet 、应用的客户、Enterprise Beans 、JSP 页面及Servlet ）都被打包成模块，并以Java Archive （JAR ）文件的形式交付。一个模块由相关的组件、相关的文件及描述如何配置组件的配置描述文件</font>
<img src ="http://www.blogjava.net/sdkdsyy/aggbug/104347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdkdsyy/" target="_blank">寿业勇</a> 2007-03-16 20:13 <a href="http://www.blogjava.net/sdkdsyy/archive/2007/03/16/104347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Tapestry入门（译作）</title><link>http://www.blogjava.net/sdkdsyy/archive/2006/10/07/73609.html</link><dc:creator>寿业勇</dc:creator><author>寿业勇</author><pubDate>Sat, 07 Oct 2006 04:18:00 GMT</pubDate><guid>http://www.blogjava.net/sdkdsyy/archive/2006/10/07/73609.html</guid><wfw:comment>http://www.blogjava.net/sdkdsyy/comments/73609.html</wfw:comment><comments>http://www.blogjava.net/sdkdsyy/archive/2006/10/07/73609.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sdkdsyy/comments/commentRss/73609.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sdkdsyy/services/trackbacks/73609.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="10" align="left" border="0">
				<tbody>
						<tr>
								<td>
										<!--插入广告JS代码-->
								</td>
						</tr>
				</tbody>
		</table>简介<br /><br /><a href="http://jakarta.apache.org/tapestry"><u><font color="#800080">Jakarta Tapestry</font></u></a>是一个开源的Java Web应用框架。你或许会说："大同小异的东西罢了."多数<br /><br />情况下，我同意你的观点，然而，只要花上些许时间研究一下，你会发现Tapestry跟别的框架大为不同，它是值得严肃对待的。<br /><br />Tapestry是一个基于控件的框架以致于用它开发Web应用类似开发传统的GUI应用。你用Tapestry开发Web应用时你无需关注以操作为中心的(operation-centric) Servlet API.引用Tapestry网站上的一句话："Tapestry用对象(objects),方法（methods）,属性（properties）替代以往的URLs和查询参数， 重新诠释Web应用开发.Tapestry 3.0即将发布，它有大量的改进和新的特性。<br /><br />Tapestry的目标<br /><br />简单性<br /><br />Tapestry应用与传统的Servlet应用相比代码量更少。大多数传统的Servlet应用包含如下厌烦和<br /><br />重复的任务：解析查询参数，处理HttpSession对象，构建URLs。Tapestry消除了传统Servelt应用中许多无趣的"衔接"代码("plumbing" code)使开发者把精力集中到应用逻辑上来。<br /><br />一致性<br /><br />Tapestry为开发Web应用的页面提供了一致的方式。这样有助于消除传统Servlet应用开发中臆测。由于所有Tapestry应用中的页面都是用相同的可复用的控件组织而成，所以工作方式是相似的。<br /><br />效率<br /><br />Tapestr应用拥有高度的可升级性，它利用缓存和对象池使每个请求的处理时间最小化。Tapestry应用拥有跟传统Servlet应用相仿的性能。<br /><br />错误反馈<br /><br />任何开发过Servlet/JSP应用的人毫无质疑有类似经历：为了找出Web.xml文件有什么错误，不得不花费大量时间察看浏览器中的堆栈信息。Tapestry拥有优秀的错误报告方式，最值得一提的是它会指出哪个文件以及那一行导致了错误。<br /><br />与Struts比较<br /><br />既然Apache Struts可能是当今应用最广泛的Web应用框架，拿Tapestry与它比较是唯一公平的。以下是一些观察比较，它们来源于为这篇文章开发的几个简单的Tapestry应用和为几个Struts工程的工作经历。<br /><br />Struts的优点<br /><br />1 一个Servlet/JSP开发者熟悉Struts无需太久。然而Tapestry的学习曲线会长一点，因为它与流行的Web应用框架不太相同 。<br /><br />2 Struts在Java社区里被广泛接受和使用。为你的项目找一个好的Struts开发人员并非难事，Tapestry近来在开发者社区里 赢得一些关注，然而仍有许多Java老手不知道Tapestry为何物。<br /><br />3 既然Struts被如此广泛的使用，所以有很多Struts资源可供参考。相比大多数开源软件，Tapestry拥有非常可观的资源和文档，但跟Struts相比仍有差距。<br /><br />Tapestry的优点<br /><br />1 你开发一个Tapestry应用无需关注Servlet API,你也无须为你的Servlet应用写一些典型的"衔接"代码。虽然Struts简化了工作，然而Servlet API 仍是你需面对的。<br /><br />2 Tapestry的页面模板除了几个特别属性和标识就是一个标准的HTML文件。 如果你是一个开发小组中的HTML设计高手，然而你不懂Java或JSP,这就给你带来很大方便。<br /><br />3 因为Tapestry页面是标准的HTML,所以可以用HTML所见即所得（WYSIWYG）编辑器编辑和预览该页。当一个页需要修改它的外观并不需要通知服务器让它重新编译JSP.<br /><br />4 Tapestry不需要一个至高的，整个应用范围的配置文件。Tapestry应用中的每一页是独立的，改变一页不会影响开发其他 页面的开发者，因为并没有一个配置文件把所有页面的浏览粘连在一起。<br /><br />5 Tapestry拥有极好的错误报告。如果你在一个页的模板或页面规范犯了一个错误，Tapestry会指出导致错误的行号。<br /><br />6 用Tapestry开发是种乐趣。这样说听上去似乎老调，然而用Tapestry开发一个Web应用相比应用其他流行的框架更为自然有趣。用Tapestry开发是应用了一种基于控件的架构，与开发传统的GUI应用非常相似。<br /><br />Tapestry 架构<br /><br />Tapestry框架是标准Servlet API的一种扩展。它需要J2SDK1.2或更高版本的J2SDK和一个与Servlet API 2.2(或更高)兼容的应用服务器/Servlet容器。<br /><br />一个Tapestry应用由许多拥有唯一名称的页面组成。一个页面由一个模板和一些可复用的控件构成。模板由标准的HTML标签和一些额外的属性和标签构成，这些额外的属性和标签是为了告诉Tapestry框架这个页面的那些部分是由Tapestry控件组成。<br /><br />简单的Tapestry应用<br /><br />为了最好的描述构建一个Tapestry页面的方方面面，我们可以看看这个Pig Latin翻译器应用的代码。这个应用只有一个页面，在这页里输入一个text值把它翻译成Pig Latin,然后把翻译好的值显示给用户。<br /><br />在Tapestry应用中每个页由3个部分组成：一个HTML模板，一个页面规范文件，一个Java类。 
<p>这里有这个页面屏幕抓图：<br /><br /><img alt="/Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226281.jpg" src="http://www.inspiresky.com/Article/UploadFiles/200602/20060215120948481.jpg" /><br /><br /><br />页面模板由标准的HTML标签和一些额外的属性和标签构成，这些额外的属性和标签是为了告诉Tapestry框架这个页面的那些部分是由Tapestry控件组成。页面模板存放在Web应用的根context目录下。通常，Tapestry在启动时会寻找和呈现一个名叫"Home"的页。虽然我们可以改变这种行为，但依照Tapestry的惯例会更简单。<br /><br />Home.html <br />    &lt;html&gt;<br />    &lt;head&gt;<br />      &lt;title&gt;Tapestry Pig Latin Translator&lt;/title&gt;<br />    &lt;/head&gt;<br />    &lt;body&gt;<br />      &lt;h1&gt;Pig Latin Translator&lt;/h1&gt;<br />      &lt;form jwcid="@Form"① listener="ognl:listeners.submit"②&gt;<br />      &lt;table border="1"&gt;<br />        &lt;tr&gt;<br />          &lt;td&gt;Value to Translate:&lt;/td&gt;<br />          &lt;td&gt;<br />            &lt;input type="text" jwcid="@TextField"③ value="ognl:inputValue"/&gt;<br />          &lt;/td&gt;<br />        &lt;/tr&gt;<br />        &lt;tr&gt;<br />          &lt;td&gt;Pig Latin:&lt;/td&gt;<br />          &lt;td&gt;<br />            &lt;jwcid="@Insert"④ value="ognl:pigLatinValue"/&gt;<br />          &lt;/td&gt;<br />        &lt;/tr&gt;<br />      &lt;/table&gt;<br />      &lt;input type="submit" jwcid="@Submit"⑤ value="Translate"/&gt;<br />      &lt;/form&gt;<br />    &lt;/body&gt;<br />    &lt;/html&gt;<br />    <br /><br />页面模板的绝大部分是普通的HTML,只有少部分Tapestry特有的属性和标签。这种模板机制的优势就是Tapestry页面模板可以在一个可见即所得的编辑器里创建和预览。描述Tapestry控件部分的标识是有限的和突出的。<br /><br />标识里的jwcid所指是被应用的Tapestry控件的Java Web Component ID.在上面代码断里，我们是隐式地使用控件。隐式的控件是指直接在页面模板里声明使用的控件，。jwcid的前缀 '@ '符号就是通知Tapestry这里声明使用了一个隐式控件。<br /><br />在上面的Pig Latin Translator页面模板里用了四个控件：Form①, TextField③, Insert④ 和Submit⑤。它们只是Tapestry框架提供的包含超过40个控件的控件库里的四个。在后面的范例中，我们将会看到如何使用显式控件。显式控件是指控件在页面规范文件里声明后再使用的控件。<br /><br />在前面的HTML模板里，使用控件的同时，也为控件指定了参数。例如控件Form①有一个listener②参数它指定了当表单提交时对应的页面类调用的方法名称。那个ognl:前缀的使用贯穿页面的HTML模板，指向的是<a href="http://www.ognl.org/"><u><font color="#0000ff">Object Graph Navigation Language </font></u></a>(OGNL)。OGNL是一个强大的开源的表达式语言，用于将页面内控件的属性绑定到页面类的属性。<br /><br />现在我们看看页面规范文件。页面规范文件是一个扩展名为page的XML文件，这个文件有许多职责，在众多职责中最基本是指定页面对应的Java类。页面规范文件存放在webapp的WEB_INF目录。<br /><br />Home.page <br />    &lt;?xml version="1.0"?&gt;<br />    &lt;!DOCTYPE page-specification PUBLIC<br />        "-//Apache Software Foundation//Tapestry Specification 3.0//EN"<br />        "<a href="http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd" target="_blank"><u><font color="#0000ff">http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd</font></u></a>&gt;<br />    &lt;page-specification class="Home"&gt;<br />        &lt;property-specification name="inputValue" type="java.lang.String"/&gt;<br />        &lt;property-specification name="pigLatinValue" type="java.lang.String"/&gt;<br />    &lt;/page-specification&gt;<br /><br />    <br />页面规范文件的根元素有一个class的属性，它指定了这个页对应的Java类。这个类必须要实现org.apache.tapestry.Ipage接口。页面规范同时页定义了两个属性(property)元素，以便Tapestry在页面类里创建新的属性。<br /><br />Tapestry框架提供了org.apache.tapestry.html.BasePage class,它实现了Ipage接口。页面类被存放在Web-INF/classes目录下，跟你的Web应用的所需要的其他类放在一起。<br /><br />Home.java <br />    import org.apache.tapestry.html.BasePage;<br />    import org.apache.tapestry.IRequestCycle;<br /><br />    public abstract class Home extends BasePage {<br />        public abstract String getInputValue();<br />        public abstract void setInputValue(String inputValue);<br /><br />        public abstract String getPigLatinValue();<br />        public abstract void setPigLatinValue(String pigLatinValue);<br /><br />        public void submit(IRequestCycle cycle) {<br />            String inputValue = getInputValue();<br />            String pigLatinValue = new PigLatinTranslator().translate(inputValue);<br />            setPigLatinValue(pigLatinValue);<br />        }<br />    }<br />    <br /><br />你要提醒的第一件事或许是这个类为什么是抽象类。它还有几个抽象方法访问inputValue，pigLatinValue属性。这里利用了Tapestry会在运行时刻创建子类的功能，这个子类会创建你在页面规范里声明的属性和生成相应的访问方法。<br /><br />在表单提交时页面类的submit方法会被调用。为什么会这样？因为我们在页面模板里将Form控件的listener属性指定为：ognl:listeners.submit。这就意味着一个名叫submit的listener会通过页面类的listeners被访问。<br /><br />所有的页面类和控件类都从org.apache.tapestry.AbstractComponent这个类继承来一个叫listeners的属性。当submit方法完成后，页面会显示被翻译好的词。<br /><br />最后讲讲Web.xml这个Web发布描述文件。Tapestry,像许多其他的流行的Web应用框架一样，由一个Servlet构成，但是还需要一个发布描述文件。那个发布描述文件应该被存放在WEB-INF目录。<br /><br />web.xml <br />    &lt;?xml version="1.0"?&gt;<br />    &lt;!DOCTYPE web-app PUBLIC<br />        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"<br />        "<a href="http://java.sun.com/dtd/web-app_2_3.dtd" target="_blank"><u><font color="#0000ff">http://java.sun.com/dtd/web-app_2_3.dtd</font></u></a>&gt;<br />    &lt;web-app&gt;<br />        &lt;display-name&gt;Tapestry Pig Latin Translator&lt;/display-name&gt;<br /><br />        &lt;servlet&gt;<br />            &lt;servlet-name&gt;tapestry&lt;/servlet-name&gt;<br />            &lt;servlet-class&gt;org.apache.tapestry.ApplicationServlet&lt;/servlet-class&gt;<br />            &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />        &lt;/servlet&gt;<br /><br />        &lt;servlet-mapping&gt;<br />            &lt;servlet-name&gt;tapestry&lt;/servlet-name&gt;<br />            &lt;url-pattern&gt;/app&lt;/url-pattern&gt;<br />        &lt;/servlet-mapping&gt;<br />    &lt;/web-app&gt;<br />    <br /><br />虽然Pig Latin翻译应用非常简单，但是它会让你对在Tapestry应用中一个页面的3个组成部分有了基本的了解。它也展示了创建一个Tapestry应用的一个页面只需写多么少的代码。<br /><br />表单输入验证<br /><br />Tapestry 提供了一些控件以便校验用户的输入。校验子系统是ValidField控件的核心。在下面的登录应用中我们将使用ValidField控件。ValidField控件位于表单内，对用户在客户端的校验提供了有用的反馈和视觉上的错误提示。<br /><br />区域化<br /><br />在Tapestry中，区域化是相当简单的。Tapestry允许文字和图形的区域化。为了区域化页面的内容，你可以为每一个添加一个properties文件，或者提供一个区域化的模板。为每个页面提供一个资源文件的方式远比管理和维护一个巨大的全局的应用范围的资源文件简单。如果页面的区域化并不仅仅只是文字信息的区域化，例如页面的布局不同或者组成的控件不同，这样情况提供区域化的页面模板就能派上用场了。我们会在下面的登录应用的使用Tapestry区域化。<br /><br />创建控件<br /><br />Tapestry发布时提供了40多个自带的控件。如果你想知道更多的关于Tapestry自带控件的信息，请参考<a href="http://jakarta.apache.org/tapestry/doc/ComponentReference/index.html"><u><font color="#0000ff">Tapestry Component Reference</font></u></a>.想看看Tapestry的控件的应用范例可访问<a href="http://www.t-deli.com/app"><u><font color="#0000ff">Tapestry Component Workbench</font></u></a>.如果你发现你需要一个Tapestry本身没提供的控件，你可以自己创建一个。创建你自己的Tapestry控件跟创建一个页面是相似的。一个典型的Tapestry控件由一个控件规范文件（XML文档），一个HTML控件模板，一个实现了org.apache.tapestry.Icomponent接口的Java类。这个议题有点超出本文的范围，但是如果你有兴趣学习如何创建你自己的Tapestry控件，你可以参考Tapestry的原创人，<a href="http://www.manning.com/lewisship/index.html"><u><font color="#0000ff">Tapestry In Action </font></u></a>一书的作者--Howard Lewis Ship写的 <a href="http://www.onjava.com/pub/a/onjava/2001/11/21/tapestry.html"><u><font color="#0000ff">Designing Tapestry Mega-Components</font></u></a> 。<br /><br />Tapestry 登录应用<br /><br />你在Pig latin翻译器应用中看到了Tapestry的一些基本特性。与其用一个复杂的应用展示Tapestry所有的特性以致于压得你揣不过气来，还不如通过一些简单的应用让你找到一点对Tapestry的感觉。下面这个应用展示Tapestry如何处理页面导航，区域化，验证和其他一些特性。</p><p>这里有一个Home页的屏幕抓图，下面跟着它的页面模板。<br /><br /><img alt="/Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226283.jpg" src="http://www.inspiresky.com/Article/UploadFiles/200602/20060215120950881.jpg" /><br /><br />Home.html <br />    &lt;html&gt;<br />    &lt;head&gt;<br />        &lt;title&gt;Welcome to the Tapestry Login Application&lt;/title&gt;<br />    &lt;/head&gt;<br /><br />    &lt;body&gt;<br />        &lt;h1&gt;Welcome to the Tapestry Login Application&lt;/h1&gt;<br />        &lt;span jwcid="@PageLink"① page="Login"&gt;Login&lt;/span&gt;<br />    &lt;/body&gt;<br />    &lt;/html&gt;<br />    <br />这个Home页的页面模板除了一个jwcid属性定义使用一个Tapestry PageLink①控件以外都是标准的HTML。<br /><br />PageLink控件生成了一个指向Login页的超链接。既然Home页没有任何动态的行为所以它不需要页面规范和页面对应的Java类。<br /><br />这里是Login页的屏幕抓图，后面跟着是它的页面模板。<br /><br /><img alt="/Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226285.jpg" src="http://www.inspiresky.com/Article/UploadFiles/200602/20060215120952592.jpg" /><br /><br />Login.html <br />    &lt;html&gt;<br />    &lt;head&gt;<br />        &lt;title&gt;<br />            &lt;span key="title"&gt;①Login&lt;/span&gt;<br />        &lt;/title&gt;<br />    &lt;/head&gt;<br /><br />    &lt;body jwcid="@Body"&gt;②<br />        &lt;span jwcid="@Conditional" condition="ognl:beans.delegate.hasErrors"&gt;③<br />            &lt;div style="color: red"&gt;<br />                &lt;span jwcid="@Delegator" delegate="ognl:beans.delegate.firstError"&gt;④<br />                    Error Message<br />                &lt;/span&gt;<br />            &lt;/div&gt;<br />        &lt;/span&gt;<br />        &lt;p style="font-weight: bold" &gt;<br />            &lt;span key="hint"&gt;Hint: Your password is your username spelled backwards.&lt;/span&gt;<br />        &lt;/p&gt;<br />        <br />        &lt;form jwcid="@Form" listener="ognl:listeners.login" delegate="ognl:beans.delegate"&gt;<br /><br />⑤<br />            &lt;table&gt;<br />                &lt;tr&gt;<br />                    &lt;td align="right"&gt;<br />                        &lt;span jwcid="@FieldLabel" field="ognl:components.inputUsername"⑥&gt;<br />                            Username:<br />                        &lt;/span&gt;<br />                    &lt;/td&gt;<br />                    &lt;td&gt;<br />                        &lt;input type="text" jwcid="inputUsername"⑦ value="simpson_h" <br /><br />size="30"/&gt;<br />                    &lt;/td&gt;<br />                &lt;/tr&gt;<br /><br />                &lt;tr&gt;<br />                    &lt;td align="right"&gt;<br />                        &lt;span jwcid="@FieldLabel" field="ognl:components.inputPassword"&gt;<br />                            Password:<br />                        &lt;/span&gt;<br />                    &lt;/td&gt;<br />                    &lt;td&gt;<br />                        &lt;input type="text" jwcid="inputPassword" hidden="true" value="" <br /><br />size="30"/&gt;<br />                    &lt;/td&gt;<br />                &lt;/tr&gt;<br /><br />                &lt;tr&gt;<br />                    &lt;td colspan="2" align="center"&gt;<br />                        &lt;input type="submit" jwcid="@Submit" value="message:login"/&gt;<br />                    &lt;/td&gt;<br />                &lt;/tr&gt;<br />            &lt;/table&gt;<br />        &lt;/form&gt;<br />    &lt;/body&gt;<br />    &lt;/html&gt;<br />    <br /><br />这个页面模板大多数是通常的HTML。我们从页面模板中可以看到Tapestry的区域化特性：它使用一个span元素，这个span元素带有一个叫key的属性，key的值映射到Login.properties文件里一个属性。一个Body控件被声明使用，因为它对客户端的JavaScript校验是必需的。<br /><br />为Form component⑤设定delegate属性激活表单输入验证。delegate属性是我们在页面规范里声明的org.apache.tapestry.valid.IvalidationDelegate的实现类。如果验证错误发生了，我们用Conditional component③控件判断delegate是否有任何错误，如果有就把第一个错误④显示给用户。如果ognl 表达式ognl:beans.delegate.hasErrors 为true,Conditional控件将显示它的内容实体。所有的页面类和控件类都从AbstractComponent继承来一个叫beans的属性。这个beans属性是一个org.apache.tapestry.IbeanProvider的实例，利用它可以通过名字取得在页面规范文件里定义的beans.FieldLabel⑥被用于为inputuserName validField控件显示标签，这个FieldLabel控件也被用来与表单的验证代理协作，指出包含错误的输入域。<br />InputUserName⑦控件是一个显示控件的例子。显式控件是指在页面规范文件声明的控件。InputUsername和inputPassword控件都是显式的，它们与FieldLabel联合显示它们的displayName属性。<br /><br />下面的是Login页的资源文件。Login.properties跟页面规范一并存放在WEB-INF目录。<br /><br />Login.properties <br />    title = Login to the Application<br />    hint = Hint: Your password is your username spelled backwards.<br />    login = Login<br />    username = Username:<br />    password = Password:<br />    invalidpassword = Invalid Password<br />    <br />Here is the page specification for the Login page. <br />Login.page <br />    &lt;?xml version="1.0"?&gt;<br />    &lt;!DOCTYPE page-specification PUBLIC<br />        "-//Apache Software Foundation//Tapestry Specification 3.0//EN"<br />        "<a href="http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd" target="_blank"><u><font color="#0000ff">http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd</font></u></a>&gt;<br /><br />    &lt;page-specification class="com.ociweb.tapestry.Login"&gt;<br />        &lt;bean name="delegate" class="org.apache.tapestry.valid.ValidationDelegate"/&gt;①<br /><br />        &lt;bean name="requiredValidator"②<br />            class="org.apache.tapestry.valid.StringValidator"&gt;<br />            &lt;set-property name="required" expression="true"/&gt;<br />            &lt;set-property name="clientScriptingEnabled" expression="true"/&gt;<br />        &lt;/bean&gt;<br /><br />        &lt;property-specification name="username" type="java.lang.String"/&gt;<br />        &lt;property-specification name="password" type="java.lang.String"/&gt;<br /><br />        &lt;component id="inputUsername" type="ValidField"&gt; ③<br />            &lt;message-binding name="displayName" key="username"/&gt; ④<br />            &lt;binding name="validator" expression="beans.requiredValidator"/&gt; ⑤<br />            &lt;binding name="value" expression="username"/&gt; ⑥<br />        &lt;/component&gt;<br /><br />        &lt;component id="inputPassword" type="ValidField"&gt; ⑦<br />            &lt;message-binding name="displayName" key="password"/&gt;<br />            &lt;binding name="validator" expression="beans.requiredValidator"/&gt;<br />            &lt;binding name="value" expression="password"/&gt;<br />        &lt;/component&gt;<br /><br />    &lt;/page-specification&gt;<br />    <br /><br />Page-specification元素的class属性和两个property-specification元素与Pig Latin翻译器应用是相似的。<br /><br />你会发现第一个新东西-bean元素①，bean元素把一个org.apache.tapestry.valid.ValidationDelegate<br /><br />的实例指定了名称"delegate"。页面HTML模板里的Form控件把它的参数delegate设定为<br />ognl:beans.delegate,就是指向了这个org.apache.tapestry.valid.ValidationDelegate实例。<br />Bean元素②把一个org.apache.tapestry.valid.StringValidator的实例指定了名称" <br />requiredValidator",以用于验证。这个bean的required属性被设为true表明使用这个bean的域是必须被验证的。这个bean的clientScriptingEnabled属性被设定为ture,表明使用这个bean的域客户端的JavaScript验证功能是激活的。RequiredValidator bean被用于验证inputUsername和inputPassword的内容。<br /><br />控件inputUsername③被控件规范声明为ValidField，ValidField是一种用于Tapestry验证子系统的特殊版本的TextField控件。Message-binding元素被用于指定inputUsername控件的displayName参数的值，这个值是用"username"为关键字从login.properties④文件里得到。InputUsername控件的validator参数被设定为requiredValidator bean,这是我们在页面规范里声明过的⑤。控件的value参数跟页面Java类的username属性绑定在一起⑥。控件inputPassword的控件规范跟控件inputUsername几乎相似，除了用于取得displayName的关键字和绑定的页面Java类的属性不同。<br /><br />通过使用ValidField控件和为表单(form)提供一个ValidationDelegate, 我们激活了Login表单的验证功能。除了服务器端的验证，Tapestry也提供了客户端的验证（利用JavaScript）。下面就是当用户提交一个表单而没有为UserName域提供值时，一个JavaScript错误对话框弹出时的屏幕抓图。<br /><br /><img alt="/Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226287.jpg" src="http://www.inspiresky.com/Article/UploadFiles/200602/20060215120955242.jpg" /><br /><br />下面就是当用户提交一个表单而没有为Password域提供值时，一个JavaScript错误对话框弹出时的屏幕抓图。<br /><br /><br /><img alt="/Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-15226289.jpg" src="http://www.inspiresky.com/Article/UploadFiles/200602/20060215120959795.jpg" /><br /><br /><br />下面就是Login页对应的Java 类。<br /><br />Login.java <br />    package com.ociweb.tapestry;<br /><br />    import org.apache.tapestry.html.BasePage;<br />    import org.apache.tapestry.IRequestCycle;<br />    import org.apache.tapestry.valid.ValidationConstraint;<br />    import org.apache.tapestry.valid.IValidationDelegate;<br /><br />    public abstract class Login extends BasePage {<br />        public abstract String getUsername();<br />        public abstract void setUsername(String username);<br /><br />        public abstract String getPassword();<br />        public abstract void setPassword(String password);<br /><br />        public void login(IRequestCycle cycle) {<br />            String username = getUsername();<br />            String password = getPassword();<br />            StringBuffer sb = new StringBuffer(username);<br />            String validPassword = sb.reverse().toString();<br />            if (password.equals(validPassword)) {<br />                cycle.activate("Success");①<br />            } else {<br />                String errorMessage = getMessage("invalidpassword");②<br />                IValidationDelegate validationDelegate =<br />                        (IValidationDelegate) getBeans().getBean("delegate");③<br />                validationDelegate.record(errorMessage,<br />                                          ValidationConstraint.CONSISTENCY);④<br />            }<br />        }<br />    }<br />    <br />跟Pig Latin翻译器应用一样，我们的页面类也是抽象的，它有抽象方法访问在页面规范里定义的属性(properties)。Tapestry会在运行时刻创建username和password属性。Login方法只是简单的验证一下用户输入的密码值是否刚好是用户名的反向。如果密码通过验证，用户将被引领导Success page①。<br /><br />如果密码输入有误，我们用关键字"invalidPassword"通过从org.apache.tapestry.AbstractComponent里继承来的getMessage()方法从Login.properties②里查找对应的资源。我们需要把密码错误信息纪录到我们在页面规范中定义的页面validation delegate中去。我们可以利用我们在页面规范中指定的名称，从页面的beans属性中找回validationDelegate③。最后，我们调用org.apache.tapestry.valid.IvalidationDelegate的record方法把将要显示给用户看的错误信息保存起来。下面就是当用户输入错误密码的提交后的屏幕抓图。<br /><br /><img alt="/Develop/ArticleImages/27/27850/CSDN_Dev_Image_2004-5-152262811.jpg" src="http://www.inspiresky.com/Article/UploadFiles/200602/20060215121003733.jpg" /><br /><br />下面就是Success页的页面模板。Success页的页面模板仅仅包含HTML标识，所以它不需要页面规范和页面<br /><br />Java类。<br /><br />Success.html <br />    &lt;html&gt;<br />    &lt;head&gt;<br />        &lt;title&gt;Successful Login&lt;/title&gt;<br />    &lt;/head&gt;<br />    &lt;body&gt;<br />        &lt;p&gt;<br />            Congratulations! You have successfully logged on.<br />        &lt;/p&gt;<br />    &lt;/body&gt;<br />    &lt;/html&gt;<br />    <br />总结<br /><br />我希望这篇文章已经向你展示了Tapestry框架在构建Web应用的是多么简单，然而优雅。Tapestry与大多数主流Web应用框架最大不同在于它让你用基于控件的方式开发，而非以操作为中心的方式开发。如果这篇文章激起了你的兴趣，我建议你把它下载下来利用它你自己的简单的Web应用。通过感受简单的应用，这是你了解这个框架的优点的唯一途径。如果你想在你的下一个项目里使用Tapestry,我强烈建议你购买<br /><a href="http://www.manning.com/lewisship/"><u><font color="#800080">Tapestry In Action</font></u></a> 这本书。我拥有这本书，对它我感到很满意。<br /><br />References<br />1 Zip file with all source code and war files from the article. (12K) <br /><br />                 <a href="http://www.ociweb.com/jnb/jnb2004_05.zip" target="_blank"><u><font color="#800080">http://www.ociweb.com/jnb/jnb2004_05.zip</font></u></a><br />2 Tapestry Home Page <a href="http://jakarta.apache.org/tapestry/" target="_blank"><u><font color="#800080">http://jakarta.apache.org/tapestry/</font></u></a><br />3 Tapestry In Action Page <a href="http://www.manning.com/lewisship/" target="_blank"><u><font color="#800080">http://www.manning.com/lewisship/</font></u></a><br />4 Tapestry Wiki <a href="http://jakarta.apache.org/tapestry/wiki_frame.html" target="_blank"><u><font color="#0000ff">http://jakarta.apache.org/tapestry/wiki_frame.html</font></u></a><br />5 OGNL page <a href="http://www.ognl.org/" target="_blank"><u><font color="#0000ff">http://www.ognl.org/</font></u></a><br />6 Tapestry Component Reference <br /><br />                 <a href="http://jakarta.apache.org/tapestry/doc/ComponentReference/index.html" target="_blank"><u><font color="#0000ff">http://jakarta.apache.org/tapestry/doc/ComponentReference/index.html</font></u></a><br />7 Tapestry Component Workbench <a href="http://www.t-deli.com/app" target="_blank"><u><font color="#0000ff">http://www.t-deli.com/app</font></u></a><br />8 Designing Tapestry Mega-Components <br /><br />                 <a href="http://www.onjava.com/pub/a/onjava/2001/11/21/tapestry.html" target="_blank"><u><font color="#0000ff">http://www.onjava.com/pub/a/onjava/2001/11/21/tapestry.html</font></u></a><br /><br /><br />注：原文地址：<a href="http://www.inspiresky.com/Article/java/2006-02-14/412.html">http://www.inspiresky.com/Article/java/2006-02-14/412.html</a><br /></p><img src ="http://www.blogjava.net/sdkdsyy/aggbug/73609.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sdkdsyy/" target="_blank">寿业勇</a> 2006-10-07 12:18 <a href="http://www.blogjava.net/sdkdsyy/archive/2006/10/07/73609.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>