上次使用Seam自動生成了一個CRUD的例子,後來想還是自己白手起家做一個例子看看,於是開始動手.
首先使用JBossTools工具生成項目,在生成項目的嚮導中,如果項目類型選擇ear,則會生成四個項目,分別對應war、ear、ejb、test,覺得這樣太過繁瑣,還是選擇war類型,又想要不使用tomcat作為運行伺服器吧,JBoss也不太熟悉.沒想到這一試倒試出問題來了,如果完全使用嚮導生成項目,選擇tomcat作為運行伺服器,則項目根本無法運行起來,總是提示缺少這個jar,那個jar.好,又換回JBoss,沒問題了.仔細看了一下,原來在自動生成項目的WebContent/WEB-INF/lib目錄中,只有大概十幾個jar,連Hibernate的jar都沒有,而在JBoss的Server/default/lib目錄下則什麼jar都有,怪不得不出錯.
第一個教訓:還是先使用JBoss作為運行環境,等整個Seam都搞熟了,再配一個Tomcat的運行環境.
繼續,將原來項目中的一個通用DAO和一個UserService拷貝過來,代碼如下,啟動伺服器報錯.分別為如下錯誤信息:
第二個錯誤解決:Caused by: java.lang.IllegalArgumentException: @PersistenceContext may only be used on session bean or message driven bean components: genericDao
既然提示@PersistenceContext只能用在SessionBean中,原來的代碼是使用的Spring框架,想了好長時間,在WebContent/WEB-INF/component.xml中看到這麼一段,那麼是不是通過@In來注入entityManager呢,修改@PersistenceContext為@In,編輯器自動提示沒有發現名稱為em的Component(這點好像不錯),於是再修改為@In("entityManager") ,重啟伺服器,該問題解決.
<persistence:managed-persistence-context name="entityManager" auto-create="true" entity-manager-factory="#{testEntityManagerFactory}"/> |
第三個錯誤解決:Caused by org.jboss.seam.RequiredException with message: "@In attribute requires non-null value: userService.genericDao"
將UserService中的@In修改為@In(create = true, required = true)解決此問題.
解決上述幾個問題后,自己的例子終於運行起來了 :-)
下一篇關於Seam In Action中對JSF的介紹及Seam如何增強JSF.
-------------------------------------------------------------------------------------------------
項目生成的代碼被分為兩個目錄,分別為Action和Model目錄,檢查JBoss中項目部署的目錄,發覺Action目錄下的代碼編譯生成的class文件被存放至WEB-INF/dev目錄下,Model目錄下的代碼編譯生成的class文件被存放至WEB-INF/classes目錄下,google了一下,發現在Seam Reference中提到這是Seam的增量式重部署,支持對JavaBean組件的增量重部署,可以加快編輯/編譯/測試的速度.
代碼如下:
public interface GenericDao { @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); } } // 實體類 @Entity @Table(name = "USER") public class User implements IUser, Serializable { // 用戶編碼 @Id private String userCode; // 用戶姓名 private String userName; } |
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" <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> |
通過這個實踐,小結一下:
1、發覺Seam確實簡化了JSF開發,但由於它涉及的新東西相對較多,與傳統的SSH走的路線不太一致,還是覺得其學習曲線比較陡峭,需要對Seam熟練掌握后(包括開發環境的搭建等)才能真正提高開發效率.
2、Seam提供了IOC的功能,有時需要跳出Spring,從一個新的角度去審視Seam.
[火星人 ] JBossSeam學習系列之四--第二個例子已經有591次圍觀