jsf里面 widgetvar 异次元属性有什么用用 ?

JSF笔记 – JSF中的三大核心组件 UI标签的详细介绍和使用举例
本文由发表于4年前 |
&被围观 6,352 views+
JSF提供了大量的UI标签来简化创建视图。这些UI标签类似于ASP.NET中的服务器组件。使用这些标签,可以通过其value,binding,action,actionListener等属性直接绑定到托管Bean的属性,实例或者方法上。
1、JSF中的三大核心组件:
a、 JSF容器管理的托管Bean
b、 JSF提供的UI标签,应用界面的UI标签直接绑定到托管Bean
c、 页面导航规则
下面我们就来介绍UI标签:
2、JSF中的UI标签:
JSF与JSP的标签的区别在于,JSF的标签可以使用value,binding,action和actionListener等属性直接绑定到托管Bean上面去。
JSF包括两组标签库:jsf_core.tld核心标签库和html_basic。tld HTML标签库。
2.1、JSF核心标签库:
f:actionListener
f:attribute
f:convertDateTime
f:convertNumber
f:converter
f:loadBundle
f:phaseListener
f:selectItem
f:selectItems
f:setPropertyActionListener
f:validateDoubleRange
f:validateLength
f:validateLongRange
f:validator
f:valueChangeListener
f:verbatim
关于个标签的详细介绍,可以参考JSF自带的帮助文档:
JSF解压目录\tlddocs\index.html
2.2、JSF的HTML标签:
h:commandButton
h:commandLink
h:dataTable
h:graphicImage
h:inputHidden
h:inputSecret
h:inputText
h:inputTextarea
h:messages
h:outputFormat
h:outputLabel
h:outputLink
h:outputText
h:panelGrid
h:panelGroup
h:selectBooleanCheckbox
h:selectManyCheckbox
h:selectManyListbox
h:selectManyMenu
h:selectOneListbox
h:selectOneMenu
h:selectOneRadio
关于个标签的详细介绍,可以参考JSF自带的帮助文档:
JSF解压目录\tlddocs\index.html
2.3、UI标签的通用属性:
JSF的UI大都会生成一个或多个HTML标签,所以使用这些UI标签有时一些属性是通用的:
immediate:是否立即处理UIInput组件和实现了ActionSource接口的UI组件上事件
rendered:指定条件表达式,当条件表达式为true时才会绘制组件
required:指定用户是否必须为组件输入值
requeredMessage:与requered一起使用,如果没有输入时提示信息
value:该组件的值绑定到托管对象上
ondblclick
onkeypress
onmousedown
onmousemove
onmouseout
onmouseover
styleClass
binding:将组件本身绑定到托管Bean
2.4、&f:view&标签的常用属性:
locale:指定国家语言
renderKitId:JSF根据该属性值选择对应的绘制器工具箱来绘制该页面
beforePhase:绑定生命周期监听器(必须有public void beforePhase(java.faces.event.PhaseEvent)形式的签名),JSF会在每个生命周期阶段(除了恢复视图)之前调用该方法。
afterPhase:绑定生命周期监听器(必须有public void afterPhase(java.faces.event.PhaseEvent)形式的签名),JSF会在每个生命周期阶段(除了恢复视图)之后调用该方法。
3、UI标签的使用举例:
3.1、&h:form&和基本输入标签的使用:
&h1&表单标签&/h1&
单行文本框:&h:inputText value="#{userbean.username }" /&&br /&
密码框:&h:inputSecret value="#{userbean.password }" /&&br /&
多行文本区:&h:inputTextarea rows="3" cols="20" /&&br /&
隐藏域:&h:inputHidden value="#{userbean.message }" /&&br /&
其中&h:inputText&和&h:inputSecret&可以指定一个size属性用于指定输入框的最大长度。
3.2、多选标签的使用:
&h1&多选标签的使用&/h1&
&h:selectManyCheckbox value="#{userbean.booklist }"&
&f:selectItem itemLabel="Core Java" itemValue="Java" /&
&f:selectItem itemLabel="Thinking in C++" itemValue="C++" /&
&f:selectItem itemLabel="Spring Internals" itemValue="Spring" /&
&/h:selectManyCheckbox&
&h:selectManyListbox value="#{userbean.booklist }" size="5"&
&f:selectItem itemLabel="Core Java" itemValue="Java" /&
&f:selectItem itemLabel="Thinking in C++" itemValue="C++" /&
&f:selectItem itemLabel="Spring Internals" itemValue="Spring" /&
&/h:selectManyListbox&
&h:selectManyMenu value="#{userbean.booklist }"&
&f:selectItem itemLabel="Core Java" itemValue="Java" /&
&f:selectItem itemLabel="Thinking in C++" itemValue="C++" /&
&f:selectItem itemLabel="Spring Internals" itemValue="Spring" /&
&/h:selectManyMenu&
使用上面的三个标签必须与&f:selectItem&或者&f:selectItems&标签结合使用,其中的&f:selectItem&3个属性的含义:
itemLabel:可视化标签值
itemValue:指定生成列表项或者复选框的值
value:与其他的UI标签的value属性不同,不是将该组件的值绑定到托管Bean,而是将该组件本身绑定到托管Bean
这三个标签的value属性值必须是一个List或者数组。
3.3、单选标签的使用:
&h1&单选标签的使用&/h1&
&h:selectOneRadio value="userbean.booklist"&
&f:selectItem itemLabel="Core Java" itemValue="Java" /&
&f:selectItem itemLabel="Thinking in C++" itemValue="C++" /&
&f:selectItem itemLabel="Spring Internals" itemValue="Spring" /&
&/h:selectOneRadio&
&h:selectOneListbox value="userbean.booklist" size="5"&
&f:selectItem itemLabel="Core Java" itemValue="Java" /&
&f:selectItem itemLabel="Thinking in C++" itemValue="C++" /&
&f:selectItem itemLabel="Spring Internals" itemValue="Spring" /&
&/h:selectOneListbox&
&h:selectOneMenu value="#{userbean.booklist }"&
&f:selectItem itemLabel="Core Java" itemValue="Java" /&
&f:selectItem itemLabel="Thinking in C++" itemValue="C++" /&
&f:selectItem itemLabel="Spring Internals" itemValue="Spring" /&
&/h:selectOneMenu&
这三个标签和前面介绍的三个标签的功能基本相似,只是这里的只能单选。
3.4、UISelectBoolean组件的使用:
&h:selectBooleanCheckbox /&
在页面上生成一个复选框,用于勾选或者取消勾选该复选框
与上面三个复选框不同,它的value属性必须绑定到托管Bean中boolean类型的属性,不需要与&f:selectItem&标签一起使用。
3.5、UICommand组件的使用:
&h1&UICommand组件的使用&/h1&
&h:commandButton value="点击" /&
&h:commandButton image="images/01.jpg" /&
&h:commandLink value="提交表单" /&
&h:commandLink shape="circle" coords="20,20,10"&
&img src="images/01.jpg" /&
&/h:commandLink&
3.6、UIOutput对应的输出组件的使用:
&h1&UIOutput对应的输出组件的使用&/h1&
&h:outputText value="#{userInfo.username }" /&
&h:outputText value="#{userbean.username }" /&
&h:outputLabel value="#{userbean.username }" /&
&h:outputLink value=""&IT宅&/h:outputLink&
&h:outputFormat value="#{userInfo.message }"&
&f:param value="arthinking" /&
&/h:outputFormat&
这里使用到了国际化资源,需要创建:
在faces-config.xml问价中加载国际化资源的配置:
&application&
&resource-bundle&
&base-name&com.itzhai.user&/base-name&
&var&userInfo&/var&
&/resource-bundle&
&/application&
然后在com.itzhai目录下创建一个国际化资源文件的basename为user:
username="arthinking"
message=用户名:{0}
3.7、panelGrid和panelGroup的使用:
&h1&panelGrid标签的使用&/h1&
&h:panelGrid columns="3" width="300px" border="1"&
&f:facet name="caption"&
&h:outputText value="表格标题" /&
&/f:facet&
&f:facet name="header"&
&h:outputText value="表格头" /&
&/f:facet&
&h:outputText value="1" /&
&h:outputText value="2" /&
&h:outputText value="3" /&
&h:panelGroup layout="block" style="color:#cfcfff"&
&h:outputText value="4" /&
&h:outputText value="5" /&
&/h:panelGroup&
&h:outputText value="6" /&
&h:outputText value="7" /&
&/h:panelGrid&
panelGrid用于生成表格,panelGroup用于把多个元素组成一个元素。
3.8、使用UIData迭代输出从数据源中获取的数据:
&h1&dataTable的使用&/h1&
&h:dataTable width="600px" border="1" value="showbook.bookList" var="book" rowClasses="odd,even"&
&f:facet name="caption"&
&h:outputText value="book list" /&
&/f:facet&
&h:column&
&f:facet name="header"&
&h:outputText&图书名&/h:outputText&
&/f:facet&
&h:inputText value="#{book.name }" size="3" /&
&/h:column&
&h:column&
&f:facet name="header"&
&h:outputText&图书分类&/h:outputText&
&/f:facet&
&h:outputLink value="#{book.url }"&
&h:inputText value="#{book.bookClass }" /&
&/h:outputLink&
&/h:column&
&f:facet name="footer"&
&h:panelGroup&
&h:outputText value="计算机书籍" /&
&/h:panelGroup&
&/f:facet&
&/h:dataTable&
下面需要在名为showbook的托管Bean中提供一个bookList数据源,可以在他的get方法中提供数据:
public List&BookInfo& getBookList(){
List&BookInfo& books = new ArrayList&BookInfo&();
books.add(new BookInfo("Core Java", "Java", ""));
books.add(new BookInfo("Core Java", "Java", ""));
books.add(new BookInfo("Core Java", "Java", ""));
其中的BookInfo类如下:
public class BookInfo {
private String bookC
public BookInfo(String name, String bookClass, String url){
this.name =
this.bookClass = bookC
this.url =
public String getName() {
public void setName(String name) {
this.name =
public String getUrl() {
public void setUrl(String url) {
this.url =
public String getBookClass() {
return bookC
public void setBookClass(String bookClass) {
this.bookClass = bookC
3.9、图像组件的使用:
&h:graphicImage value="images/01.jpg" alt="图像01" /&
这个标签将生成HTML的img标签。
除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:
指弹吉他 && 技术文档分类:
在线文档经过高度压缩,下载原文更清晰。
淘豆网网友近日为您收集整理了关于Seam JSF Faces的文档,希望对您的工作和学习有所帮助。以下是文档介绍:Seam JSF Faces Seam 全称是 Jboss Seam,是一个 Java EE 5 框架。它通过把 JSF 与 EJB3.0 组件合并在一起,以及利用 J DK5.0 的Annotation 技术,从而为开发基于 Web 的企业应用程序提供一个最新的模式。Seam 可以让你把 EJB 组件直接绑定到 JSF 页面。Seam 还可以把 JBPM 流程定义直接地集成到应用程序中。Seam 的主要特点是:适应快速开发、简化框架的趋势。具体来说,还有以下几个特点:1.支持 JSF,有丰富的组件库2.支持 EJB3,但也可以脱离 EJB3.参数和方法绑定4.增强的会话管理,支持多种生命周期5.使用注解的方式代替 XML 配置,减少代码量提高开发效率6.整合现有易用的数据层框架,包括 JPA、Hibernate 等7.集成其他常用工具和组件:JBPM,spring,邮件,权限管理,动态语言Seam 的官方网站是://articles/jboss-seam 深入浅出 JBoss Seam什么是 Seam? /articles/jboss-seamJBoss Seam 是“Java EE(来源:淘豆网[/p-8473891.html]) 5.0 的一个轻量级的框架”。这是什么意思?难道 Java EE(Enterprise Edition) 5.0 本身不是一套“框架吗”?为什么在官方规范之外,还需要另外一个框架?好吧,我们就将 seam 看作是本应该被包括在 Java EE 5.0 中的一个“遗漏的框架”吧。它在 Java EE 5.0 框架的上层,为所有的在企业 Web 应用中的组件提供了一个统一的、易于理解的编程模型。它同样使基于状态的应用和业务流程驱动的应用的开发易如反掌。换句话说,Seam 致力于开发者生产力和应用扩展性。1. 整合和强化 Java EE 框架Java EE5.0 的核心框架是 EJB(Enterprise JavaBeans)3.0 和 JSF(JavaServer Faces)1.2。EJB 3.0(以下简称 EJ B3)是基于一个POJO(Plain Old Java Objects)的业务服务和数据库持久化的轻型框架。JSF 是一个基于 MVC(Model-View-Controller)的(来源:淘豆网[/p-8473891.html]) Web 应用框架。大多数的 Web 应用都将包含有业务逻辑的 EJB3 组件和 Web 应用前端显示的 JSF 组件。EJB3 和 JSF 虽然互补,但是他们是根据各自的理念设计的独立的框架。例如,EJB3 使用注解(annotation)来配置服务,而 JSF 使用的是 XML 文件。更进一步讲,EJB3 和JSF 组件在框架层面上是互不敏感的。要整合 EJB3 和 JSF,开发者必须手动地构造 facade 对象(如:JSF 支持 bean),将业务组件与 Web 页面和样板代码(又称 plumbing 代码)联结起来,以便能跨框架调用方法。将这些技术粘合起来是 Seam 的职责之一。Seam 打破了 EJB3 和 JSF 之间的人工层,它为整合 EJB3 和 JSF 提供了一个一致的,基于注解的途径。只需要个别简单的注解,Seam中的 EJB3 业务组件就能直接被用来支持 JSF Web 表单或者处理 Web UI 事件。Seam 允许开发者将“同一种东西”——有注解的POJOs——应(来源:淘豆网[/p-8473891.html])用与所有的应用组件。与其他 Web 框架开发的应用相比,Seam 应用概念简洁,同样的功能却需要较少的代码(在 JAVA和 XML 中)。如果没有耐心,或者想要快速预览,一个 Seam 到底有多简单,你可以现看看本文描述的 hello world 一例。在 JSP 来说困难的任务, Seam 可以轻易的完成。例如,JSF 头疼的一个问题就是过分依赖 HTTP POST。这使得将一个添加到书签中的 JSF 网页,通过 HTTP GET 访问相当困难。但是有了 Seam,生成一个 REST 网页是非常容易的。Seam 提供了一系列 JSF 组件标签和注解,增加了“web 友好”和 JSF 应用的网页效率。同时,Seam 拓展了 EJB3 到 POJO 的组件模式, 从 web 层到业务层都有了状态上下文。进一步说,Seam 整合了一系列主要的其他开放源代码框架,例如 jBPM、JBoss Rules(又名 Drools)、JBoss Portal、JBoss Microcontainer 等等。S(来源:淘豆网[/p-8473891.html])eam 不仅能将它们“有机结合”起来,而且可以像整合 JSF 和 EJB3 一样强化原有的框架。Seam 位于 Java EE 5.0 底层,但它的应用并不局限与 Java EE 5.0 服务器。一个 Seam 应用可以部署在 J2EE 1.4 应用服务器和Tomcat 服务器上。这意味着现在能在 Seam 应用中得到产品化支持。1 + 1 & 2或许有这样一种误解,认为 Seam 仅仅是将各种不同框架串起来的另外一个集成框架。Seam 提供了它自身管理的状态上下文,允许框架通过注解和 EL(表达式语言)表达式与其他框架进行深度整合。整合的程序来自于 Seam 开发者对第三方框架的认知。2. 一个为 ORM 设计的 Web 框架对象关系映射(ORM)解决方案在当今企业应用中广为使用。但是,大多数当前的业务和 web 框架并不是为 ORM 设计的,它们并不在整个 Web 交互生命周期——从请求来临到响应完成——管理持久上下文。这就导致了包括可怕的 Lazy Initialization E(来源:淘豆网[/p-8473891.html])xception在内的各种 ORM 异常,带来了如“数据传输对象(DTO)”等丑陋的伎俩(ugly hacks)。Gavin King 发明了 Seam,同时他也发明了在世界上广为使用的 ORM 解决方案 Hibernate。为了继承和发扬 ORM 的最佳实践,Seam 进行了重新设计。有了 Seam,就不必再写 DTO,你所做的就是延迟加载。因为扩展后的持久上下文就如同一个自然的高速缓存,可以减少和数据库的交互,ORM 的性能就会被极大地改进。进一步讲,因为 Seam 整合了 ORM 层、业务层和表示层,开发者就能够在表示层直接展示 ORM 对象,也能把数据库验证注解用于输入表单,以及重新定向 ORM 例外到定制的错误页面。3.专为有状态 Web 应用而设计Seam 是专为有状态 Web 应用而设计的。Web 应用是天生的多用户应用,电子商务应用天生也是有状态的和有事务的。但是,大多数已有 Web 应用框架是面向无状态应用的。开发者必须操作 HTTP 会话(session)对象来管理用户状态(来源:淘豆网[/p-8473891.html]),与核心业务逻辑无关的代码不仅会混乱你的应用,而且带来了一系列的性能问题。在 Seam 中,所有的基础应用组件天生地有状态。它们使用起来要比 HTTP session 容易,因为它们的状态由 Seam 公开管理。没有必要在 Seam 应用中编写引起麻烦的状态管理代码——只需在其组件上注解其做用域、生命周期方法以及其他状态属性,Seam 就会掌管其他[译者注:指这些组件的生命周期]。Seam 状态组件要比 HTTP 会话(session)能更好的管理用户状态。例如,你能有多个“会话”进行,每个“会话”由在一个 HTTP 会话(session)中一系列的 Web 请求和业务方法调用组成。进一步说,在 Seam 中,数据库缓存和事务能自动与应用的状态相连。Seam 在内存中自动保存数据库更新,等到对话结束后提交到数据库。内存中的缓存能大大减轻复杂状态应用中数据库的负载。除了以上这些,Seam 支持整合开源 JBoss jBPM 业务程序引擎,大大提升了 Web 应用中的状态管理。你现在能为一个机构中(来源:淘豆网[/p-8473891.html])不同工作人员(诸如客户、经理、技术支持人员等等)的指定工作流程,利用工作流程来驱动应用,而不是依赖用户界面事件处理和数据库。4. 支持 Web 2.0Seam 为 Web2.0 应用进行了充分的优化。它给 AJAX(异步 JavaScript 和 XML,增加网页交互的一种技术)提供了多种支持——从内置“零 Javascript”的 AJAX 组件到有 AJAX 支持的 JSF 组件,再到定制的 JavaScript 库,Seam 为浏览器端的 Javascript 对象提供了直接访问 Seam 服务器组件的途径。Seam 提供了一个先进的并发模型,有效的管理来自同一用户的多个 AJAX 请求。对于 AJAX 应用,不断增长的数据库负载是一个巨大的挑战。与一个非 AJAX 应用相比,一个 AJAX 应用要向服务器发送的更频繁的请求。一但数据库必须响应这些 AJAX 请求,那么数据库就不堪重荷。Seam 中的状态持久上下文正如一个内存中的缓存,它能在会话始末保存信息,最终帮助减少数据库交互。We(来源:淘豆网[/p-8473891.html])b2.0 应用往往为其数据使用复杂关系模型(例如,一个网络交际站点所做的就是处理和显示“用户”之间的关系),对于这些站点,延迟加载对于 ORM 层至关重要。否则,一个简单的查询就能级联地加载整个数据库。正如我们前面所讨论过的,Seam 是现今唯一一个正确支持 Web 应用延时加载的 Web 框架。5.依赖双向映射的 Pojo 服务Seam 是一个“轻量级”框架,因为它使用 POJO(plain old Java objects)作为服务组件。在应用中,POJO 没有使用接口或抽象类来&钩住&组件。当然,问题是如何使 POJO 交互来组成这个应用?它们如何与容器服务(例如,数据库持久化服务)交互?Seam 通过使用一个流行的、被称作依赖注入(DI)的设计模式联结所有 POJO 组件。在这个模式下,Seam 框架管理着所有组件的生命周期。当一个组件需要使用另外一个时,它通过注解(annotation)向 Seam 声明此依赖。Seam 依据应用当前状态得到这个依赖组件,并将它注(来源:淘豆网[/p-8473891.html])入到所需求的组件中。通过拓展依赖注入概念,一个 Seam 组件 A 不但可以构造另外一个组件 B,而且把此组件 B“抛还”给 Seam 以备其他组件(例如组件C)以后使用。这类双向依赖管理甚至都广泛的应用于简单的 Seam web 应用中(例如第二章的 hello world 一例)。在 Seam 术语中,我们称这个为“依赖双向映射”。6.非常规的配置[译者注:指以隐式映射为主题,以显式映射为例外的配置方式]使 Seam 易用的主要设计原则是“非常规的配置”。其思想是为这些组件提供一系列默认行为,开发者只需要在预期行为非默认的时候,显示地配置组件。例如, 当 Seam 将组件 A 作为属性注入到组件 B 时,默认地,组件 A 刚会以组件 B 被注入的属性的名称命名。Seam 里还有很类似的细节。总的结果是 Seam 中配置元数据要比其他 Java 框架简单的多。因此,大多数的 Seam 应用能通过一系列简单的 Java 注解进行充分配置。开发者从减化的复杂度中受益匪浅,最后,与其他 Java (来源:淘豆网[/p-8473891.html])框架相比,用更少的代码实现同样的功能。7.避免滥用 XML或许你已经注意到,Java 注解在表述和处理 Seam 配置元数据时扮演着重要的角色。通过这样的设计使框架更易于操作。在 J2EE 发展早期,XML 曾经被看作配置管理的“圣杯”。框架设计者将所有的配置信息,包括 Java 类和方法名称都统统丢进 XML 文档,而不考虑对开发者所带来的后果。反省后,发现这是个严重的错误。XML 配置文档太过重复。开发者必须重复代码中已有的信息,从而将配置和代码联结起来。这些重复使应用易于出错(例如,一个拼写错误的类名可能在运行时显示为一个难于调试错误)。缺少合理的默认配置进一步使这一问题复杂化。事实上,在一些框架中,相当数量的样板代码伪装为 XML,可能相当于或者超过实际应用中 JAVA 代码的数量。对于 J2EE 开发者,XML 的滥用通常被称为“XML 地狱”。Java 社区认识到了 XML 的滥用问题,并且已经非常成功地用 Java 代码中的注解取代了 XML。EJB3 是 Java 官方标准化机构促进 Java企业组件中注解使用的一项成果。EJB3 完全可选择的使用 XML 文档,它向正确方向迈出了积极的一步。Seam 加入了 EJB3 的注解,为整个 web 应用拓展了基于注解的编程模型。当然,XML 对于配置数据并非完全不利。Seam 设计者认识到 XML 适用于指定页面流程或者定义业务流程的 web 应用。XML 文档使开发者集中地管理整个 web 应用的工作流程成为可能,同时也反对将配置信息分散于 java 源文件中。工作流程很少能与源代码耦合,因此 XML 文档中并不需要重复键入已存在于代码中的信息。8.为测试而设计Seam 为了易于测试而重新设计。因为所有的 Seam 组件都是注解过的 POJO,它们易于进行单元测试。开发者仅仅通过利用常规的Java new 关键词来构造实例,然后在测试框架(例如 JUnit 或者 TestNG)中运行任何方法。如果需要测试多个 Seam 组件的交互,开发者则逐个实例化这些组件,然后手动建立它们的相互关系(也就是显示地使用 setter 方法,而不是依靠 Seam 依赖注入功能)。集成测试整个 Seam 应用比较复杂,因为开发者必须在 Seam 容器中运行应用。Seam 用嵌入的轻量级容器来帮助该类测试。在测试框架中,开发者能按步骤地加载 Seam 容器,然后运行测试。9. 卓越的工具支持对于一个聚焦于开发者生产力的应用框架,开发工具的支持至关重要。Seam 发布了一个基于命令行的生成器,称作 SeamGen。SeamGen 类似于 Ruby-On-Rails 中的生成器,它支持诸如从一个数据库生成完整 CRUD 应用的功能,聪明的开发者会通过诸如“编辑/保存/在浏览器重新载入”的步骤、有测试支持的特性,来改进 web 应用。但更重要的是,SeamGen 生成项目不依赖于主流的 Java集成开发环境,如 Eclipse Beans。有了 SeamGen,开发者可以随时入门。10. 让我们开始编码吧总而言之,Seam 为 JavaEE 应用削减了开发费用,同时,增加了 Java EE 5.0 不具有的强大的新功能。在下节(节选自本书第二章), 我们将给您展示一些实际代码例子来阐述 Seam 如何工作的。你能通过网站 m/下载到本书中所有的例子的源代码。Seam Hello WorldJBoss Seam 是 EJB3 和 JSF 中间的粘合剂,这是 Jboss Seam 最基本的和最广泛的应用。通过被 Seam 管理的组件,Se am 允许这两个框架之间无缝(不是有意双关的)的集成。它为整个 web 应用拓展了基于注解的 EJB3 POJO 编程模型。在层与层之间,没有了必需的手动 JNDI 查找,没有了冗长的 JSF 支持 bean 的声明,没有了过多 facade 方法,没有了艰辛的对象传递,快哉!继续在 Seam 中使用 JavaEE 模式在传统的 java EE 应用中,一些设计模式,例如 JNDI 查找、XML 声明组件、值对象、facade 是被强制使用的。Seam 用基于注解的 POJO 消除了这些人为的需求。但是,当 Seam 应用中真正需要它们的时候,仍然可以自由地使用这些模式。编写一个 Seam web 应用概念上很简单。你只需要编码出下列组件: 实体对象代表数据模型。实体对象可能是 JPA 或者 Hibernate 中的 POJO 对象。它们自动地映射到关系数据库表。 SF web 页面展示了用户界面。页面通过表单捕获用户的输入,并且显示结果。表单域与其数据显示数据库表, 这些表被映射到实体 bean 或者实体 bean 的集合上。 EJB3 会话 bean 或者注解过的 Seam POJO 可以作为 JSF Web 页面的 UI 事件处理器。它们处理封装在实体 bean 中的用户输入,为下一步(或者页面)生成显示的数据对象。所有以上组件均由 Seam 自行管理,它们在运行时被自动注入到正确的页面或者对象。例如,当用户单击按钮提交一个 JSF 表单,Seam 就会自动解析表单域并构造一个实体 bean。然后,Seam 将实体 bean 传入同样被 Seam 构造的事件处理器会话 bean 中来处理。开发者不需要在代码中管理组件的生命周期和组件之间的相互关系。依赖处理过程中,没有样板代码和 XML 文件。本章中,我们使用 hello world 一例来明确展示 Seam 如何粘合一个 web 应用。该例子工作如下:用户能在 web 表单中输入其名字来“问候”Seam。一旦她提交了表单,应用则保存她的名字到一个关系数据库中,并且显示所有已经“问候”过 Seam 的用户。该项目示例在该书下载的源代码中的 HelloWorld 文件夹中。为了建立它,你必须安装 Apache ANT 1.6 版本以上(http://ant./)。进入 HelloWorld 目录,运行命令 ant,则会生成 build/jars/helloworld.ear 文件,可以直接拷贝该文件到 Jboss AS 实例的 server/default/deploy 目录下。现在,启动 JBoss AS 并且打开网址http://localhost:8080/helloworld/。为了运行本书中的例子,我们建议您使用 JEMS GUI 安装程序安装一个与 Seam 兼容的 JBoss AS。您可以从http://labs./portal/jemsinstaller/downloads 下载 JEMS 安装程序。如果您需要更多安装 JBoss AS 和应用部署帮助,请参见附录 A,“安装和部署 JBoss AS”欢迎使用示例作为模板,快速开始你自己 Seam 项目(参见附录 B “使用应用示例作为模板”)。或者,你能使用命令行工具 SeamGen (参见第四章“快速应用开发工具”)自动生成项目模板,包括所有的配置文件。本章中,我将花少量的时间来阐释源代码项目中的目录结构。相反,我们将集中讨论代码和配置,这也是开发者建立一个 Seam 应用必需的。如此,我们就能将知识应用到任何一个项目结构,而不需要受模板的限制。源代码目录一个 Seam 应用由 java 类和 XML 或文本配置文件组成。本书的项目例子中,java 源代码文件在 src 目录中,网页在 view 目录中,所有的配置文件都在 resources 目录中。更多信息请看附件 B,使用应用示例作为模板。1. 创建一个数据模型Helloworld 应用中的数据模型仅仅是一个有 name 和 id 属性的 person 类。注解@Entity 告诉容器映射该类到一个关系数据库表,每个属性对应表中一个字段,每个 person 实例相当于表中的一条记录。因为 Seam 采用非常规的配置方式,容器为表名和字段中仅仅使用类名和属性名。属性 id 上的@Id 和@GeneratedValue 注解暗示 id 字段是主键,它的值是应用服务器为每个保存到数据库的 peron对象自动生成。@Entity@Name(&person&)public class Person implements Serializable {private S@Id @GeneratedValuepublic long getId() {}public void setId(long id) { this.id = }public String getName() { }public void setName(String name) {this.name =}}Person 类中最重要的注解是@Name,它为这个将要注册于 Seam 中的 Person bean 指定了名称。在其他 Seam 组件中(例如,页面和会话 bean)中,开发者能指直接使用“person”来引用被管理的 Person bean。2. 将数据模型映射到 web 表单在 JSF 页面中,我们使用 Person bean 来支持表单输入文本域。#{person.name}符号指代名为“person”的 Seam 组件的 name 属性, 名为“person”的 Seam 组件是 Person 实体 bean 的一个实例。&h:form&Please enter your name:&br/&&h:inputText value=&#{person.name}& size=&15&/&&br/&&mandButton type=&submit& value=&Say Hello& action=&#{manager.sayHello}&/&&/h:form&通过以下的实体表单,JSF 页面显示了数据库中所有已经向 Seam 说“hello”的用户。用户名单列表存储在一个名为“fans”的Seam 组件中,它是一个 List 对象。JSFdataTable 通过遍历列表,每一行显示一个 Person 对象。Fan 标记是 fans 列表的迭代子。&h:dataTable value=&#{fans}& var=&fan&&&h:column&&h:outputText value=&#{fan.name}&/&&/h:column&&/h:dataTable&图 2.1 显示了 Hello World 网页当用户点击“Say Hello”按钮提交表单,Seam 用输入数据构造了该 person 组件。然后它调用了名为“manager”的 Seam 组件的sayhello()的方法(像这样,#{manager.sayHello}是表单提交按钮的 UI 事件处理器),这就在数据库中保存了 person 对象并且刷新了 fans 列表。名为 manager 的组件是一个 EJB3 的会话 bean, 我们将在下节讨论该话题。2. 处理 web 事件Seam 中的名为 manager 的组件是会话 bean ManagerAction,正如该类中@Name 注解指定的。ManagerAction 类有 person 和 fans 两个属性,这两个属性被@In 和@Out 所注解。@Stateless@Name(&manager&)public class ManagerAction implements Manager {@In @Outprivate P@Outprivate List &Person&注解@In 和@Out 在 Seam 编程模型中处于核心。因此,让我们看看到底它们在这里是做什么的。注解@In 告诉 Seam,在此会话 bean 中,执行任何一个方法之前,Seam 就会把由 JSF 表单构造的名为 person 组件赋给该 person 字段(通过依赖注入)。开发者能为@In 中的注入的组件指定一个任意的名称,但是如果没有指定,如这里所示,Seam 会将同类型以及同名称的组件注入到该字段中。注解@Out 告诉 Seam,在执行任何方法后,Seam 会将属性 fans 值和属性 person 的值都赋给被 Seam 管理的同名的组件。在 Seam 中,我们将这个操作称作“依赖抛出”。以此,在 ManagerAction.sayHello()方法中,我们仅仅需要更新属性 fans 和属性 person 的值,它们会自动显示在页面上。什么是双向映射在 Seam 文件中,有时你就会看到术语“双向映射”。它指的是被 Seam 管理的组件和 Seam 管理上下之间的注入和抛出因为 person 属性已经通过注入持有了表单数据,sayHello()方法仅仅是通过 JPA EntityManager 将它保存到数据库中,JPAEntityManager 也是通过@PersistenceContext 注入的。当方法返回之后,它便更新了 fans 和 person 对象并且把这两个对象抛出。方法 sayHello()一般会返回 null,预示着在调用之后,更新的数据模型将在当前的 JSF 页面显示。@PersistenceContextprivate EntityMpublic String sayHello () {em.persist (person);person = new Person ();fans = em.createQuery(&select p from Person p&).getResultList();}除了一些细节,我们基本完成了。可能你已经注意到,ManagerAction bean 类实现了 Manager 接口。为了符合 EJB3 会话 bean 规范,我需要一个能列出 bean 中所有业务方法的方法。下面是接口 Manager 代码,幸运的是,用任何高级 IDE 工具都能轻松地自动生成这个接口。@Localpublic interface Manager {public String sayHello ();}这就是在 Hello World 例子中需要的所有代码。后面两章小节将涵盖 Seam 应用的其他方法和配置。如果开发者为了自己的小型数据库应用想立即编码和定制 helloworld 项目,那么现在就可以跳过本章的剩余部分。4. 更易于理解的 seam 编程模型现在我们已经大致了解了 Hello World 的应用。但是我们还有一些重要的话题继续,例如其他折中途径以及前面代码没有涉及到重要特性,我们将在本节讨论这些话题。它们能帮助开发者对 seam 更深刻的理解,但是如果你没有耐心,可以直接跳过本节,需要的时再来阅读。4.1 Seam POJO 组件上例中,我们用一个 EJB3 会话 bean 实现了应用逻辑,但是我们并不局限于 EJB3 组件。事实上,Seam 中任何一个有@Name 注解的POJO 都能被转化为一个可管理的组件。例如,我们能将 ManagerAction 转化为一个 POJO,而不是一个 EJB3 session bean。@Name(&manager&)public class ManagerAction {@In (create=true)private EntityM... ...}使用 POJO 取代 EJB3 bean 有正反两方面意见,使用 POJO 编程时很简单,因为它们不需要 EJB3 特有的注解和接口(参见上文)。如果你的所有业务组件都是 Seam POJO, 那么你就能不依赖 EJB3 应用服务器,运行你的 Seam 应用(参见 23 章,没有 EJB3 的 Seam)。但是,POJO 比 EJB3 的功能少,因为 POJO 不能获得 EJB3 容器服务。在不依赖 EJB3 的 Seam 中丧失的 EJB3 服务就包括以下几点: @PersistenceContext 注入在 POJO 中不在管用。为了在一个 Seam POJO 中得到 EntityManager,开发者不得不在 Seam 配种文件中初始化 EntityManager,然后使用 Seam 注解@In 将它注入到 POJO 中。 POJOs 中将不在支持方法级别事务声明(declarative method-level transaction)。相反,你可以配置 Seam 来划分事务,可以从收到 web 请求开始直到响应页面产生结束。 Seam POJO 不是消息驱动组件。不支持注解为@Asynchronous 的方法。不支持容器安全管理。没有事务或者组件级别的持久上下文。Seam POJO 中的所有的持久上下文都是经过拓展的(更多细节请参见 7.1 “默认的对话作用域”)。没有集成容器管理的体系结构(例如,JMX 控制台服务)。 Seam POJO 方法中没有 Java RMI。 Seam POJO 不能是注解为@WebService 组件。没有 JCA 集成。所以当在 EJB3 容器中进行部署时,为什么每个人都想使用 POJO 组件?答案就是,POJO 组件对于纯“业务逻辑”组件非常有益。POJO 为其他组件代理了数据访问、消息传递和其他基本功能。例如,我们能使用 POJO 组件操纵 Seam 数据访问对象,这对“业务逻辑”POJO 是非常有用的,因为它们可以在需要的时候,在其他框架中被重用。但是总的来说,它们的应用要比 EJB3 组件少,特别是在中小型应用中。所以,本书的大多数例子我们都使用 EJB3 组件。4.2 易于测试我们已经在第一章中提到,Seam 为了不依赖容器的方便的测试,进行了重新设计。在 helloworld 项目中,我们在测试文件夹中包括了单元测试和集成测试这两个测试用例。在纯 Java SE 环境下,Seam 测试体系模拟了数据库、 JSF、Seam 上下文以及其他应用服务器服务,只要运行 ant test 命令就能运行所有的测试。4.3 基于 Getter 和 Setter 的双向映射在 Hello World 一例中,我们已经展示了通过成员变量对 Seam 组件进行的双向映射,你也能通过 Getter 和 Setter 方法对组件进行双向映射。例如,以下代码就工作的很好。private Pprivate List &Person&@Inpublic void setPerson (Person person) { this.person =}@Outpublic Person getPerson () {}@Outpublic List &Person& getFans () {}虽然以上的 getter 和 setter 方法看似轻微,利用 getter 和 setter 方法的双向映射真正的价值在于能其加入定制逻辑来操纵双向映射的过程。例如,你可以验证被注入的对象或者快速地从数据库重新得到被抛出的对象。4.4 避免过度的双向映射在 Hello World 一例中,通过将数据组件作为业务组件的属性,可以轻易的减少或者消除双向映射。在 JSF 页面中,通过这种方式,开发者只需要引用业务组件,而不需要在业务组件和数据组件之间的双向映射。例如,开发者可以修改 ManagerAction 类为以下所述。依赖双向映射是一个非常实用的设计模式。但是,正如其他设计模式,过度使用就会有害。过度的依赖双向映射让代码变得难以阅读,因为开发者必须理解每个注入的组件出自何处。过度的依赖双向映射也能增加性能消耗,因为双向映射是在运行时进行。@Stateless@Name(&manager&)public class ManagerAction implements Manager {private Ppublic Person getPerson () {}public void setPerson (Person person) { this.person = }private List &Person&public List&Person& getFans () {}... ...}接下来,我们在页面上引用的属性如下:&h:form&Please enter your name:&br/&&h:inputText value=&#{manager.person.name}&/&&br/&&mandButton type=&submit& value=&Say Hello& action=&#{manager.sayHello}&/&&/h:form&... ...&h:dataTable value=&#{manager.fans}& var=&fan&&&h:column&&h:outputText value=&#{fan.name}&/&&/h:column&&/h:dataTable&最后,具有了依赖管理的 Seam 是多用的。通常用数据访问业务组件封装数据是一项好的实践,特别是针对有状态业务组件。4.5 JSF 中的页面导航本例中,只有一个页面。每次点击按钮后,JSF 页面会重新显示更新过的数据模型。显然,大多数 web 应用多于一个页面。在 JSF中,一个用户界面事件处理器能通过返回导航规则名称,决定下一步该显示哪个页面。例如,开发者可以在 navigation.xml 中定义以下导航规则。&navigation-case&&from-e&anotherPage&/from-e&&to-view-id&/anotherPage.jsp&/to-view-id&&/navigation-case&之后,如果 sayHello()方法返回一个名为“another page”的字符串,JSF 下一步就该展示 anotherPage.jsp。UI 事件处理器决定了接下来要显示哪个页面,从而为我们带来了有步骤的控制。4.6 通过 EntityManager 访问数据库JPA(Java Persistence API)EntityManager 管理着关系数据库表与实体 bean 之间的映射。EntityManager 在运行时由应用服务器创建。你能使用注解@PersistenceContext,注入一个 EntityManager 的实例。EntityManager.persist()方法将实体 bean 存为与之对应数据表的一条记录。EntityManager.query()方法运行 SQL 化的查询,并以实体 bean 集合形式从数据库返回数据。更多细节请参考 JPA 文件中关于如何使用 EntityManager 和查询语言。在本书中,我们只用最简单的查询语句。默认地,EntityManager 将数据存于嵌入的 HSQL 数据库中。如果在本机上运行 Jboss AS,可以通过以下步骤,为 HSQL 数据库开启一个 GUI 控制台:访问 http://localhost:8080/jmx-console/,点击database=localDB,service=Hypersonic MBean 服务,之后,点击在 startDatabaseManager 方法下方的“invoke”按钮。你就可以从控制台执行任意 SQL 指令。5. 配置和打包下面,我们将转移话题,讨论配置文件和应用程序打包。实际上,你可以通过 Seam Gen 命令行工具,生成几乎所有的配置文档和构造脚本文件。或者你也可以简单的重用在示例中的源文件。所以,如果你想首先学习 Seam 编程技术,但又担心接下来的配置和部署,这个是很正常的。你可以完全放心地跳过本节,需要的时候可以再次阅读。本节中,我们集中探讨 Seam EJB3 组件配置,JBoss AS 外的 Seam POJO 配置和部署当然是可行的。大多数 Seam 配置文件都是 XML 文档。但是等等!我们刚才不是承诺 Seam 能让我们摆脱 J2EE 和 Spring 中的 XML 地狱吗?为什么它又有了 XML 文档呢? 是的,XML 文档确实有很多用处。XML 文档非常适合部署阶段的配置(例如 web 应用的根 URL 和后台数据库的定位)。因为它允许我们在部署阶段改变配置而不需要改变和重新编译源代码。它也适合粘合应用服务器中的不同子系统(例如,配置如何让 JSF 组件与 Seam EJB3 组件交互)。XML 文档也非常适合表示层相关内容(例如网页和页面导航流程)。我们反对在 XML 文档中重复已经存在于 Java 源代码中的信息。开发者很快就会发现,这个简单的 SeamEJB3 应用有多个 XML 配置文档,每个文档那个都非常简短,并且没有一个包含存在于 Java 代码中的信息。换句话说,Seam 中没有“XML 代码”。进一步讲,XML 文档中的大多数内容都是静态的。所以开发者能在自己的 Seam 应用中轻松地重用这些文档。如何使用示例作为自己的应用模板的介绍,请参见附录 B——使用应用示例作为模板。我们将用下面几页来详细讲解示例应用的配置文档和打包后的目录结构。如果你没有耐心看下去,而且很满意这个应用模板,你可以跳过以下内容。不管怎样,不再罗嗦, 我们一起来了解 hello world 示例是如何进行配置和打包的。为了构建一个 JBoss AS 的部署Seam 应用,我们必须将以上所有 java 类和配置文档打包为企业应用程序归档(EAR)。该例中,EAR 文件是 helloworld.ear。它包含了三个 JAR 文件那个和两个 XML 配置文档。helloworld.ear|+ app.war //包含 Web 页面等|+ app.jar //包含 Seam 组件|+ jboss-seam.jar // Seam 库|+ META-INF|+ application.xml|+ jboss-app.xml源代码目录在此项目的源代码中,resources/WEB-INF 目录包含属于 app.war/WEB-INF 目录的配置文档。resources/META-INF 目录包含属于 app.jar/META-INF 和 helloworld.ear/META-INF 的文档。Resources 根目录包含属于根目录 app.jar 的文档。application.xml 文档列出了在 EAR 中的 JAR 文件,并为该应用指定了根 URL。&application&&display-name&Seam Hello World&/display-name&&module&&web&&web-uri&app.war&/web-uri&&context-root&/helloworld&/context-root&&/web&&/module&&module& &ejb&app.jar&/ejb& &/module&&module& &java&jboss-seam.jar&/java& &/module&&/application&jboss-app.xml 文档为该应用指定了类加载器,每个 EAR 应用的类加载器应该有一个唯一的名称。这里我们使用应用程序名作为类加载器的名称,以避免重复。&jboss-app&&loader-repository& helloworld:archive=helloworld.ear &/loader-repository&&/jboss-app&jboss-seam.jar 是 Seam 发布 Seam 类库。app.war 和 app.jar 文档由我们来建构。所以,下面我们要研究 app.war 和 app.jar。5.1. WAR 文件app.war 是按照 Web 应用程序归档规范打包的 JAR 文件,它包含页面和标准的 JSF/Seam 配置文档。你还可以将 JSF 特有的类库文件放入 WEB-INF/lib 目录(例如 jboss-seam-ui.jar)。app.war|+ hello.jsp|+ index.html|+ WEB-INF|+ web.xml|+ faces-config.xml|+ components.xml|+ navigation.xmlweb.xml 文档是所有 java EE web 应用必需的。JSF 用它来配置 JSF servlet 控制器,Seam 用它来拦截所有的 web 请求。该配置文档的相当标准。&web-app version=&2.4& xmlns=&http://java./xml/ns/j2ee& xmlns:xsi=&...& xsi:schemaLocation=&...&&&!-- Seam --&&listener&&listener-class& org.jboss.seam.servlet.SeamListener &/listener-class&&/listener&&!-- MyFaces --&&listener&&listener-.apache.myfaces.webapp.StartupServletContextListener &/listener-class&&/listener&&context-param&&param-name& javax.faces.STATE_SAVING_METHOD &/param-name&&param-value&client&/param-value&&/context-param&&servlet&&servlet-name&Faces Servlet&/servlet-name&&servlet-class& javax.faces.webapp.FacesServlet &/servlet-class&&load-on-startup&1&/load-on-startup&&/servlet&&!-- Faces Servlet Mapping --&&servlet-mapping&&servlet-name&Faces Servlet&/servlet-name&&url-pattern&*.seam&/url-pattern&&/servlet-mapping&&context-param&&param-name&javax.faces.CONFIG_FILES&/param-name&&param-value&/WEB-INF/navigation.xml&/param-value&&/context-param&&/web-app&faces-config.xml 文档是 JSF 标准的配置文档,Seam 用它来将其***添加到 JSF 生命周期中。&faces-config&&lifecycle&&phase-listener& org.jboss.seam.jsf.SeamPhaseListener &/phase-listener&&/lifecycle&&/faces-config&navigation.xml 文档为多页面应用包含 JSF 页面导航规则。因为 hello world 示例只有一个简单的页面,ponents.xml 文档包含 Seam 特有的配置选项,除 jndi-pattern 属性以外,其他都不依赖于应用。该属性必须包括 EAR 文档的名称,以便 Seam 通过其的 JNDI 全名访问 EJB3 bean。&components ...&&core:init jndi-pattern=&helloworld/#{ejbName}/local& debug=&false&/&&core:manager conversation-timeout=&120000&/&&/components&5.2. Seam 组件 JAR 包app.jar 文档包含所有的 EJB3bean 类(实体 bean 和会话 bean)以及 EJB3 相关的配置文档。app.jar|+ Person.class // entity bean|+ Manager.class // session bean interface|+ ManagerAction.class // session bean|+ seam.properties // empty file but needed|+ META-INF|+ ejb-jar.xml|+ persistence.xmlseam.properties 文档这儿是空但必需的,因为 Jboss 要通过它知道此 JAR 文件包含 Seam EJB3 bean 类,并且相应地处理注解。ejb-jar.xml 文档包含额外的配置信息,这些信息能重载或者增补 EJB3 bean 上的注解。在一个 Seam 应用中,它能将所有的 EJB3类加入 Seam ***。我们能在所有的 Seam 应用中重用该文档。&ejb-jar&&assembly-descriptor&&interceptor-binding&&ejb-name&*&/ejb-name&&interceptor-class& org.jboss.seam.ejb.SeamInterceptor &/interceptor-class&&/interceptor-binding&&/assembly-descriptor&&/ejb-jar&persistence.xml 文档为 EJB3 实体 bean 配置了后台数据源。本例中,我们只是使用了被嵌入到 JBoss AS 中默认的 HSQL 数据库(也就是 java:/DefaultDS 数据源)。&persistence&&persistence-unit name=&helloworld&&&provider& org.hibernate.ejb.HibernatePersistence &/provider&&jta-data-source&java:/DefaultDS&/jta-data-source&&properties&&property name=&hibernate.dialect& value=&org.hibernate.dialect.HSQLDialect&/&&property name=&hibernate.hbm2ddl.auto& value=&create-drop&/&&property name=&hibernate.show_sql& value=&true&/&&/properties&&/persistence-unit&&/persistence&这样,以上就是一个简单 Seam 应用所需的所有配置和打包。我们将在以后讨论到本书的更高级的主题时,涵盖更多的配置选项和类库。再次强调一下,Seam 应用入门最简单的方法就是,不要担心这些配置文件,只需要从已有的应用模板做起。6. 为何这么简单?这就是 hello world 应用,三个简单的 Java 类,一个 JSF 页面,一组静态配置文件。我们已经有了一个完整的数据库驱动的 web 应用。整个应用只需要的是少于 30 行的 Java 代码,没有一处“XML 代码”。但是如果开发者有 PHP 背景,你可能仍然会问“何以这么简单?我能在 php 中使用更少的代码吗?”好吧,答案就是 Seam 应用在理论上要比 PHP(或者其他任何一种脚本语言)应用简单的多。Seam 组件模式允许我们,有所控制地,可维护地给应用增加更多的功能。我们很快就会发现,Seam 组件使开发有状态的和有事务的 web 应用变得易如反掌。对象关系映射框架(例如:实体 bean)允许我们将注意力放在抽象数据模型上,而不需要处理数据库特有的 SQL 语句。本文是基于该书的第一章和第二章。后面的章节中,我们继续讨论如何使用 Seam 组件继续开发复杂的 Seam 应用。参见本书目录来查看本书的所有主题。请看 Gavin King 的两个访谈录来查看以往关于 Seam 的话题。 JBoss Seam 1.1 Indepth: An Interview with Gavin King JBoss Seam 1.0: rethinking web application architecture关于作者Dr. Michael Yuan 是 JBoss Seam: Simplicity and Power Beyond Java EE 5.0 一书的作者。该书探讨了下一代 web 应用框架。他同时也是 Nokia Smartphone Hacks 一书和其他三本技术读物的作者。Michael 潜心研究轻量级企业 web 应用,终端对终端的移动应用开发。你可以通过他的博客联系他。AWT
JSFre/archive//113149.htmlJSF 当时就是为了和 的 WebForm 竞争才推出的, 虽然目前效果还不甚理想, 主要来讲就是 Java 是一个分裂的世界, 大部分厂商/开源人士都是希望把用户绑定过去然后大赚支持费用(如 Jive, Hibernate, JBoss, beans 和 Eclipse...), 所以难听点 Web 层的现状就是一盘散沙, 所以程序员做开发不得不对付一大堆框架.JSF 的竞争对手是 Tapstry,而不是 struts。我们最后选的是 Tapstry。原因很简单:够成熟,组件够多。页面的复杂度其实是一个系统中最让人头痛的。只是因为什么都是可视的,所以很少有设计者重视它。JSF 与 Tapstry 之间不好说,个人觉得 Tapstry 的优势在于使用 html 和页面导航简单一些,这个 JSF 由于 IDE 不够成熟要落下风;JSF 的优势在于 scope 控制要简单一些,另外 JSF 有钱有势。RIA ajax 也是一种 RIA,Applet 也是一种 RIA,java web start 也是一种 RIA,flash 和 flex 也是。你是指 flex 吗?现在不是有 ajax4jsf 之类的开源项目么,我觉得将来基于 jsf 上的 ajax 技术肯定会流行,我可以和人打赌jsf 最大的优点是组件化、可视开发,可是带来更多的视图混杂(tag 和 html 混杂在一起),在某种程度上,我很欣赏 html 的做法,(打个比方有个模块 a)a.html 负责展示结构,a.js 负责 a.html 上的所有事件,a.css 负责 a.html 上面所有的展示和风格——这也是 xul 和 xaml 的做法,也是 flex 的做法,毫无疑问,这几个最新技术的特征意味着将来的趋势。之所以 web 开发觉得不爽是因为 js 的不规范,js 开发的低效率,恐惧的兼容性——它太脚本了,他至少应该像个语言才可以。这也是 j2ee web 开发的困境:普通的 web 开发 j2ee 绝对没有问题,可是碰到高交互性,就需要 ajax 支持才可以; 可是 js 太不规范了。也就带来开发的低效率。于是要用一个规范一点的东西来代替 ajax 的事件响应,于是就用 jsf 组件。可是 jsf 组件最终是要在 jre 里面执行,这意味我们一个事件先发到服务器,然后处理,然后返回,常常的,还需要 js 帮助处理——他并没有解决 js的简单问题却带来了更多的复杂性。ps:我这里引用了 xaml 和 flex,是为了说明视图、处理分离是趋势。我并不认为 xaml 和 flex 会代替 web 或者什么。。。。。耸人听闻的吹牛。web 有他无可救药的优点(你只需要提供一个 url 就可以提供自己的服务,而 url 是无形的,不需要占用用户的任何资源)而任何所谓的 c/s 或者类似的 c/s 都需要一个图标(webstart 可能好一点) xaml,rcp 适合在特别的群体里使用,受众比较小,分众的。组件只是 JSF 一个比较平淡的优势,通过组件和其他 BEAN 数据传递以及由容器管理的 WEB 状态才是 JSF 的强项。自定义组件当然也是积累代码的好办法。使用了 JSF,我们只需关心流程而不用关心具体数据的显示等情况我自己没研究过 JSF 和 Tapstry,是同产品组的同事研究的。他专门做了一个 JSF 和 Tapstry 的选择验证。最后得出的主要结论之一就是 JSF 还不够成熟,UI 组件(widget)不够多。所以我们最后选了草民。抽象一下表现层框架应有的技术架构,下图可以说所有表现层框架技术都必须实现的功能架构图:在上图 MVC 模式基础上,一个表现层框架无外乎要实现图中的三个功能:1.在当前页面能够显示一个组件对象的内容;而不是象纯 JSP 那样,需要在 Jsp 页面写入“调用对象方法”的 Java 代码。2.当用户按下页面的提交按扭或链接后,事件发生,这时应该触发服务器端并将当前页面的参数提交给服务器。这种机制表现在 Form 表单提交和有参数的链接&a href=&&&&/a&3.从一个页面视图直接跳转到另外一个页面视图,单纯的导航作用。我们通过下表来比较这三种框架在实现上图各个功能时技术细节,从而得出他们的异同点和偏重点。Struts Tapestry3.0 JSF在 View 显示的组件要求组件必须继承 ActionForm分显式调用和隐式调用组件 ponent普通 POJO 无需继承Managed Bean组件在 View显示粒度View 页面只能显示与表单对应的 ActionForm,配置中Action ActionForm 页面一般只能 1:1:1 关系。可将组件嵌入页面任何一行,对使用组件数量无限制。同 Tapestry页面分区 tiles使用 Tiles 标签库实现,需要另外 tiles-def.xml 配置文件组件有自己的视图页面,通过调用组件即直接实现多个页面组合。强大自然的页面组合是其特点。通过组件+标签库实现Subview,但如需重用Layout,还要结合 Tiles.页面跳转使用标签库 html:link 中写明目标 URL,URL 名称需要对照配置文件的 path 命名,与组件 Action 耦合。URL 名称是目标的组件名称,不涉及 URL 和路径等操作,方便稳固。类似 Struts,也需要在配置文件中查找,与组件分离。参数传递使用 html:link 时传递参数超过一个以上处理麻烦。直接调用组件,直接赋予参数,没有参数个数限制参数分离传递给组件事件触发通过表单提交 submit 激活,不能细化到表单里字段。能够给于表单每个字段贴一个事件,事件组件必须实现 PageListener 接口同 Tapestry,事件组件必须实习 ActionListener 接口选择 tapestry 有如下几大优点:1、最彻底的 MVC 开发框架,页面代码全部由 HTML 标准标签组成,页面美工人员无须了解特别的标签定义。2、可重用组件开发节省开发资源,一句话:越开发越轻松3、优秀的页面流转开发。传统方式都是基于 URL 实现激活页面流转,而 tapstry 除了此方式,你还可象开发普通 java 类一样实现page 页面流,更重要的是,还可由此实现页面类的复用。4、丰富的组件资源。除了官方维护的资源外,还可找到一大堆的 tapestry 组件库。5、超强的扩展性。tapestry 是一个真正的开放性架构,说白了,你觉得哪个服务不爽,你就可写个替代它。6、生命力超强,不断的自我更新、发展。tapestry4.0 与 3.0 相比简直就是另一个飞跃,如支持 jdk1.5 的 Annotations,仅这点开源产品中目前还只看到一个支持 portlet JSR-168,又一个顺应潮流的 web 开发支持。规划中的 4.1 将支持页面静态化,这不正是众多开发人员的另个期待吗?7、tapestry 的开发人员稳定。不是一个两个人在那里单打独斗,而是有一群人在开发和支持 tapestry 的进程。8、tapestry 技术成熟吗?基于 tapestry 的软件和大网站已经很多了,国外的:软件如 SeaView 内容管理系统、WidenTM DigitalAsset Management System网站:/ ,/ ,https://merchant./enroll/app ,e.htm ,http://admissions.chicagogsb.edu/admissions/app国内的:软件如 ,网站如:http://love./dating/app ,http://dbi.lib.ntu.edu.tw/libraryList/ ,/ ,/ ,uts 组件模型缺点Struts 组件编程必须限定在 Action/ActionForm/JSP 这三个框框中做文章,难度相对比较大,而 Tapestry/JSF 则没有太多这些技术框框限制,两者在组件编程方面更让编程者自由一些,方便一些,这也是组件型框架的优势吧。三者概述JSF 在很大程度上类似 Struts,而不是类似 Tapestry,可以说是一种 Struts 2.0,都是采取标签库+组件的形式,只是 JSF 的组件概念没有象 Struts 那样必须继承 ActionForm 的限制;JSF 在事件粒度上要细腻,不象 Struts 那样,一个表单一个事件,JSF 可以细化到表单中的每个字段上。JSF 只有在组件和事件机制这个概念上类似 Tapestry,但是不似 Tapestry 那样是一个完全组件的框架,所以,如果你做一个对页面要求灵活度相当高的系统,选用 Tapestry 是第一考虑。Struts/JSF 则适合在一般的数据页面录入的系统中,对于 Struts 和 JSF 的选用,我目前个人观点是:如果你是一个新的系统,可以直接从 JSF 开始;如果你已经使用 Struts,不必转换,如果需要切换,可以将 JSF 和 Tapestry 一起考虑。另外,JSF/Tapestry 不只是支持 Html,也支持多种客户端语言如 WML 或 XUI 等。这三者之间关系:如果说 Struts 是左派;那Tapestry 则是右派;而 JSF 则是中间派,中庸主义是 SUN 联盟的一贯策略。播放器加载中,请稍候...
该用户其他文档
下载所得到的文件列表Seam JSF Faces.doc
文档介绍:
Seam JSF Faces Seam 全称是 Jboss Seam,是一个 Java EE 5 框架。它通过把 JSF 与 EJB3.0 组件合并在一起,以及利用 J DK5.0 的Annotation 技术,从而为开发基于 Web 的企业应用程序提供一个最新的模式。Seam 可以让你把 EJB 组件直接绑定到 JSF 页面。Seam 还可以把 JBPM 流程定义直接地集成到应用程序中。Seam 的主要特点是...
内容来自淘豆网转载请标明出处.

我要回帖

更多关于 dnf属性强化有什么用 的文章

 

随机推荐