??xml version="1.0" encoding="utf-8" standalone="yes"?> 首先使用JBossTools工具生成目Q在生成目的向gQ如果项目类型选择earQ则会生成四个项目,分别对应war、ear、ejb、testQ觉得这样太q繁琐,q是选择warcdQ又惌不用tomcat作ؓq行服务器吧Q因为JBoss也不太熟(zhn)。没惛_q一试倒试出问题来了,如果完全使用向导生成目Q选择tomcat作ؓq行服务器,则项目根本无法运行v来,L提示~少q个jarQ那个jar。好Q又换回JBossQ没问题了。仔l看了一下,原来在自动生成项目的WebContent/WEB-INF/lib目录中,只有大概十几个jarQ连Hibernate的jar都没有,而在JBoss的Server/default/lib目录下则什么jar都有Q怪不得不出错?/p>
W一个教训:q是先用JBoss作ؓq行环境Q等整个Seam都搞熟了Q再配一个Tomcat的运行环境?/strong> l箋Q将原来目中的一个通用DAO和一个UserService拯q来Q代码如下,启动服务器报错。分别ؓ如下错误信息Q?/p>
W二个错误解冻ICaused by: java.lang.IllegalArgumentException: @PersistenceContext may only be used on session bean or message driven bean components: genericDao 既然提示@PersistenceContext只能用在SessionBean中,因ؓ原来的代码是使用的Spring框架Q想了好长时_在WebContent/WEB-INF/component.xml中看到这么一D,那么是不是通过@In来注入entityManager呢,修改@PersistenceContext为@InQ编辑器自动提示没有发现名称为em的ComponentQ这点好像不错)Q于是再修改?/font>@In("entityManager") Q重启服务器Q该问题解决?/font> W三个错误解冻ICaused by org.jboss.seam.RequiredException with message: "@In attribute requires non-null value: userService.genericDao" UserService中的@In修改?font color="#0080c0">@In(create = true, required = true)解决此问题?/font> 解决上述几个问题后,自己的例子终于运行v来了 :-) 下一关于Seam In Action中对JSF的介l及Seam如何增强JSF?/p>
------------------------------------------------------------------------------------------------- 目生成的代码被分ؓ两个目录Q分别ؓAction和Model目录Q检查JBoss中项目部|的目录Q发觉Action目录下的代码~译生成的class文g被存放至WEB-INF/dev目录下,Model目录下的代码~译生成的class文g被存放至WEB-INF/classes目录下,google了一下,发现在Seam Reference中提到这是Seam的增量式重部|Ԍ支持对JavaBeanlg的增量重部vQ可以加快编?~译/试的速度?/font> 代码如下Q?/p>
通过q个实践Q小l一下: 1、发觉Seam实化了JSF开发,但由于它涉及的新东西相对较多Q与传统的SSH走的路线不太一_q是觉得其学习曲U比较陡峭,需要对Seam熟练掌握后(包括开发环境的搭徏{)才能真正提高开发效率?/p>
2、Seam提供了IOC的功能,有时需要蟩出SpringQ从一个新的角度去审视Seam?/p>
1、生成Sem web目 2、输入项目的相关信息Q如下图Q?/p> 注意Q如果是W一ơ用EclipseQ需要配|Target Runtime和Target Server?/p> 3、然后一路nextQ到最后一步时Q如果是W一ơ用,也要注意配置Seam Runtime和Connection ProfileQ如下图。最后点击finish按钮Q即可创建Seam目?/p> 4、生成项目后Q在Eclipse中共出现了四个项目,如下Q?/p> 此时q行JBossServer服务器,讉Khttp://localhost:8080/seamfirst链接Q出现如下图面Q此时Seam帮我们生成了一个框Ӟ包含了基本的d和退出功能,q有一个首c?/p> 5、l!使用Seam生成单表的CRUD操作。本步骤前提Q有一个mysql数据库,数据库中有一个Customer表,该表有IDQintcdQ、customernameQvarchar2cdQ、customerdescQvarchar2cdQ、createdateQdatecdQ、emailQvarchar2cdQ五个字Dc在seamfirst目上点d键,选择Seam Generate Entities菜单Q弹出界面如下图Q?/p> 单击finish按钮后,再运行JBoss Server服务器,讉Khttp://localhost:8080/seamfirstQ发觉菜单栏上多了一个Customer List菜单Q单L链接Q即可进行Customer的添加、删除、修攏V查询操作,虽然生成的界面不是很好看Q也不是很符合我自己的操作习惯,但是功能倒是完备?/p> 以后若是修改了Seam提供的代码自动生成的模板Q然后再使用该功能,惛_生成的页面就W合自己的项目要求了Q记下一W,先不它?/p> 生成的代码分析: 生成的代码主要有两部分,一部分为Java代码Q一部分为页面代码?/p> Java代码包括如下三个c: CustomerHome和CustomerListcM都用了@Name annotationQ这样在面中就可以直接讉KSession Bean中的Ҏ(gu)了,辑ֈ了Seam表现层和业务层直接融合的目标?/p> 面代码包括如下文gQ?/font> 刚开始看q段代码Ӟ困惑我的有两个地?/p> xW一个用JBossTools生成的Seam例子完成了,好像很简?:-)
public Object get(Class clazz, Serializable id);
public void save(Object object);
public void update(Object object);
public void remove(Class clazz, Serializable id);
public void remove(Object obj);
}
@Name("genericDao")
public class GenericDaoImpl implements GenericDao {
@PersistenceContext ----> @In("entityManager")
private EntityManager em;
public Object get(Class clazz, Serializable id) {
if (id == null) return null;
else return em.find(clazz, id);
}
}
public interface UserService {
public void findAllUsers();
}
@Name("userService")
public class UserServiceImpl implements UserService, SecurityUserService {
@In ----> @In(create = true, required = true)
protected GenericDao genericDao;
private List<User> resultList = null;
public List<User> getResultList() {
if (resultList == null) {
this.findAllUsers();
}
return resultList;
}
public void setResultList(List<User> resultList) {
this.resultList = resultList;
}
public void findAllUsers() {
String hql = "from User order by userCode";
resultList = this.genericDao.query(hql);
}
}
// 实体c?br />
@Entity
@Table(name = "USER")
public class User implements IUser, Serializable {
// 用户~码
@Id
private String userCode;
// 用户姓名
private String userName;
}
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:rich="http://richfaces.org/rich"
template="layout/template.xhtml">
<ui:define name="body">
<rich:panel>
<f:facet name="header">User Search Results</f:facet>
<rich:dataTable id="userServiceTable"
var="user"
value="#{userService.resultList}">
<h:column>
<f:facet name="header">
<h:outputText value="UserCode"/>
</f:facet>
<h:outputText value="#{user.userCode}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="UserName"/>
</f:facet>
<h:outputText value="#{user.userName}"/>
</h:column>
</rich:dataTable>
</rich:panel>
</ui:define>
</ui:composition>
Exception during request processing:
Caused by java.lang.IllegalStateException with message: "No phase id bound to current thread (make sure you do not have two SeamPhaseListener instances installed)"
org.jboss.seam.contexts.PageContext.getPhaseId(PageContext.java:163) org.jboss.seam.contexts.PageContext.isBeforeInvokeApplicationPhase(PageContext.java:175) org.jboss.seam.contexts.PageContext.getCurrentWritableMap(PageContext.java:91) org.jboss.seam.contexts.PageContext.remove(PageContext.java:105) org.jboss.seam.Component.newInstance(Component.java:2102) org.jboss.seam.Component.getInstance(Component.java:1987) org.jboss.seam.Component.getInstance(Component.java:1966) org.jboss.seam.Component.getInstance(Component.java:1960) org.jboss.seam.Component.getInstance(Component.java:1933) org.jboss.seam.Component.getInstance(Component.java:1928) org.jboss.seam.faces.FacesPage.instance(FacesPage.java:92) org.jboss.seam.core.ConversationPropagation.restorePageContextConversationId(ConversationPropagation.java:84) org.jboss.seam.core.ConversationPropagation.restoreConversationId(ConversationPropagation.java:57) org.jboss.seam.jsf.SeamPhaseListener.afterRestoreView(SeamPhaseListener.java:389) org.jboss.seam.jsf.SeamPhaseListener.afterServletPhase(SeamPhaseListener.java:228) org.jboss.seam.jsf.SeamPhaseListener.afterPhase(SeamPhaseListener.java:194) com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:175) com.sun.faces.lifecycle.Phase.doPhase(Phase.java:114) com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:104) com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) javax.faces.webapp.FacesServlet.service(FacesServlet.java:265) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83) org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:38) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:177) org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:267) org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:380) org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:507) org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:54) org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69) org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:432) org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157) org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262) org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446) java.lang.Thread.run(Thread.java:619)
Google了一下,有h讲是JBoss4.2.3GA版本的BUGQ赶紧下载了JBoss4.2.2GAQ再试一切正常!
不知q会不会有其它莫名的BUG?.....
又在满江U的|站上找了seam_reference2.0的中文文档,主要看了《the contextual component model》一章,看完以后感觉Seam最核心的地方就是其contextual component model了,不过看完q一章以后只是对Seam有个大概的了解,对其具体的内容,l节q缺乏进一步的了解Q对其优炏V缺点也~Zq一步的认识?/p>
然后又找C《Seam in Action》的?sh)子书,看了一点之后还是觉得这本电(sh)子书写得好,内容l织的很好,不象seam_reference后面的章节仅仅是|列seam的各功能?/p>
今天把Seam in Action的第一章草草看了一遍,第一章讲q的内容ȝ如下Q?/p>
1、什么是Seam
在Seam in Action中,没有SeamUC为web frameworkQ而是其UCؓapplication stack。SeamJava EE中的EJB3、JSF、JPA/Hibernate、JAAS{技术融合在一P提供了更Ҏ(gu)使用的方式,比如conversation、page flows、buisness precesses、rule-based security、JavaScript(Ajax) remoting、PDF rendering、emaill合、charting、file uploads、Groovy integration{,用以化web开发?/p>
2、Seam的目?
化web开?
3、Seam如何集成各类技?/p>
在Seam中将EJB3.0中的Session Bean作ؓJSF的managed beanQ直接将表现层和业务层衔接在一P使得Session Bean可以直接讉Kweb相关数据Q比如request、session、application、JSF的FacesMessage、Component Tree{。而在不用SeamӞ一般都是用JSF back bean来作现层和业务层之间的中介?
使用annotation中的@Name标注替代了JSF的faces-config.xml中关于managed bean的配|?
Seam提供?U类型的上下文,其中属于SeamҎ(gu)的两U上下文cd分别为:Conversation Context、Business process Context?
Seam提供了统一的组件注册、annotation、异帔R|、方法拦截、统一的EL表达式等功能。其中Seam对其理的组件拦截过E如下图Q?/p>
4、Seam的核心竞争力
- Seam对JSF最被认可的改进是消除了在配置文g中声明managed bean?
- Prerender page actions
- Managed request parameters (for a given page)
- Intelligent stateless and stateful navigation
- Transparent JSF data model and data model selection handling
- Fine-grained exception handling
- Page-level security (per view ID)
- ZAnnotation的表单验?
- Bookmarkable command links (solving the “everything is a POST” problem)
- Entity converter for pick lists
- Conversation controls
- Support for preventing lazy initialization exceptions and nontransactional data access in the view
用一q图可以很好的说明这句话的含?/p>
引入了有状态的变量范围QINTRODUCING STATEFUL VARIABLE SCOPESQ?/p>
Spring中提供了The Session In View FilterQ得persistence manage可以在一个请求中存在Q避免了常见的LazyInitializationException。在Seam中,扩展的Persistence Context可以跨越多个h。其实扩展的Persistence Context是Conversation Context、Business Process Context的基?/p>
Seam提供了两U方式将Ajax集成到Seam应用中,一U是使用hAjaxҎ(gu)的JSFlgQ如RichFaces和ICEFacesQ另一U是可以在浏览器中用JavaScript直接调用服务端的lg?/p>
Seamq提供了另外一U意义上的RichQ即PDF、mail{功能集成到Seam应用中?/p>
从目前我个h的理解来看,Seam的作用与能力如下Q?/p>
但由于Seam整合了如此多的框Ӟ带来的一个最大的~点Q?font color="#ff0000">学习曲线陡峭Q在SSH非常行的今天,需要面对很多新技术(JSF、EJB3、JPA{)Q对于一个新手来说难度比较大Q如果想使Seam被更多的开发h员用,必须加强它的文档Q目前的文档q是太少了?/p>
学习JBossSeam之前最好对相关技术有一定的了解Q比如:
然后下蝲相关的YӞ如下Q?/p>
环境的配|都比较单,基本都是解压卛_Q有如下注意事项Q?/p>
上述配置好后Q启动JBoss ServerQ然后至SEAM_HOMEQ假定ؓSeam的安装目录)/examples/registration目录下,q行ant explode命oQ即可编译部|registration应用至JBoss Server中,最后访问:http://localhost:8080/seam-registration 卛_体验Seam提供的第一个exampleE序 :-)
http://www.javaworld.com.tw/roller/ingramchen/entry/2005_9_20_JBossSeamKingofStateful_