首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JBoss Seam 學習系列四:自訂 Seam 專案實戰與核心註解解析

     編輯:Java 相關知識

從零建立 Seam 專案:自訂 DAO、Service 與 Facelets 整合實戰

延續 JBoss Tools 自動產生專案經驗,本文實作自訂 Seam 專案,解決 @PersistenceContext 注入失敗、@In 注入設定、增量式熱部署機制等核心議題。

專案建立關鍵決策

  • 選擇 WAR 而非 EAR:EAR 產生 4 子專案過於繁瑣,WAR 單一結構適合中小專案
  • 首選 JBoss AS 而非 Tomcat:JBoss 內建完整 Seam 依賴庫,Tomcat 需手動管理大量 JAR (連 Hibernate 都缺)

核心代碼實作與問題解決

1. 通用 DAO 介面與實作

public interface GenericDao {
    Object get(Class clazz, Serializable id);
    void save(Object object);
    void update(Object object);
    void remove(Class clazz, Serializable id);
    void remove(Object obj);
    // ... 其他查詢方法
}

@Name("genericDao")
public class GenericDaoImpl implements GenericDao {
    // 錯誤:@PersistenceContext 僅適用 Session Bean
    // @PersistenceContext 
    // 修正:使用 Seam 管理的 EntityManager
    @In("entityManager")
    private EntityManager em;

    public Object get(Class clazz, Serializable id) {
        if (id == null) return null;
        return em.find(clazz, id);
    }
    // ... 其他實作
}

2. Service 層實作

@Name("userService")
public class UserServiceImpl implements UserService, SecurityUserService {
    // create=true 自動建立元件、required=true 強制注入
    @In(create = true, required = true)
    protected GenericDao genericDao;

    private List<User> resultList = null;

    public List<User> getResultList() {
        if (resultList == null) findAllUsers();
        return resultList;
    }

    public void findAllUsers() {
        String hql = "from User order by userCode";
        resultList = this.genericDao.query(hql);
    }
}

3. 實體類別

@Entity
@Table(name = "USER")
public class User implements IUser, Serializable {
    @Id
    private String userCode;
    private String userName;
    // getter/setter 省略
}

4. Facelets 頁面 (userList.xhtml)

<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="https://www.w3.org/1999/xhtml"
    xmlns:s="https://jboss.com/products/seam/taglib"
    xmlns:ui="https://java.sun.com/jsf/facelets"
    xmlns:f="https://java.sun.com/jsf/core"
    xmlns:h="https://java.sun.com/jsf/html"
    xmlns:rich="https://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>

關鍵問題解決紀錄

錯誤訊息原因解決方案
@PersistenceContext may only be used on session beanPOJO 元件不支援 EJB 註解改用 @In("entityManager") 注入 Seam 管理的持久化上下文
@In attribute requires non-null value: userService.genericDao元件未自動建立且注入失敗加上 @In(create=true, required=true)

Seam 增量式熱部署機制

專案代碼分為 Action 與 Model 兩目錄:

  • Action 目錄編譯輸出至 WEB-INF/dev — 支援熱重載
  • Model 目錄編譯輸出至 WEB-INF/classes — 標準類別路徑

此機制加速「編輯-編譯-測試」循環,修改 Action 層代碼無需重啟伺服器。

心得總結

  1. Seam 確實簡化 JSF 開發,但涉及新概念多 (Context、Bijection、Conversation 等),學習曲線陡峭
  2. Seam 內建 IOC 容器,需跳脫 Spring 思維重新理解 @In/@Out/@Name 等註解語意
  3. 建議先熟悉 Seam 核心概念與開發環境,再投入實際專案,才能發揮生產力優勢
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved