1.3. Seam のクリック可能な一覧 : メッセージサンプル


クリックするとデータベースの検索結果を一覧表示できる機能は、あらゆるオンラインアプリケーションの非常に重要な部分です。 Seam は JSF に加えて特殊な機能を提供することで EJB-QL や HQL でのデータ問い合わせを容易にし、 JSF <h:dataTable> を使ってクリック可能な一覧としてそれを表示します。メッセージサンプルがこの機能を示しています。

1.3.1. コードの理解

このメッセージサンプルは 1 つのエンティティ Bean (Message)、1 つのセッション Bean (MessageListBean)、1 つの JSP から構成されています。

1.3.1.1. エンティティ Bean : Message.java

Message エンティティ Bean は、タイトル、テキスト、メッセージの日付と時刻、そしてメッセージが既読か否かを示すフラグを定義します。

例1.12 Message.java

@Entity
@Name("message")
@Scope(EVENT)
public class Message implements Serializable {
    private Long id;
    private String title;
    private String text;
    private boolean read;
    private Date datetime;
  
    @Id @GeneratedValue
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
  
    @NotNull @Length(max=100)
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
  
    @NotNull @Lob
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }
  
    @NotNull
    public boolean isRead() {
        return read;
    }
    public void setRead(boolean read) {
        this.read = read;
    }
  
    @NotNull 
    @Basic @Temporal(TemporalType.TIMESTAMP)
    public Date getDatetime() {
        return datetime;
    }
    public void setDatetime(Date datetime) {
        this.datetime = datetime;
    }
}
Copy to Clipboard Toggle word wrap

1.3.1.2. ステートフルセッション Bean : MessageManagerBean.java

前述のサンプル同様、 このサンプルは 1 つのセッション Bean (MessageManagerBean) から構成され、 フォームにある両方のボタンに対応するアクションリスナーメソッドを定義します。 前述のサンプルと同様、 ボタンの 1 つは一覧からメッセージを選択してそのメッセージを表示します。 もう 1 つのボタンはメッセージを削除します。
ただし、 はじめてメッセージ一覧のページに移動したときのメッセージの一覧取得も MessageManagerBean の役割となります。 ユーザーがこのページに到達するにはいろいろな経路があり、 必ずしも JSF アクションがすべての経路で先行するわけではありません。 (たとえば、 お気に入りからそのページに行く場合、 必ずしも JSF アクションを呼び出す必要はありません。) したがって、 メッセージ一覧の取得作業はアクションリスナーメソッドではなく Seam の ファクトリメソッド で行われなければなりません。
メッセージの一覧をサーバー要求にまたがってメモリにキャッシュしたいので、 ステートフルセッション Bean でこれを行います。

例1.13 MessageManagerBean.java

@Stateful
@Scope(SESSION)
@Name("messageManager")
public class MessageManagerBean 
    implements Serializable, MessageManager
{
    @DataModel                                                        
    private List<Message> messageList;
        
    @DataModelSelection                                               
    @Out(required=false)                                              
    private Message message;
        
    @PersistenceContext(type=EXTENDED)                                
    private EntityManager em;
        
    @Factory("messageList")                                           
    public void findMessages()
    {
        messageList = em.createQuery("select msg " + 
                                     "from Message msg" + 
                                     "order by msg.datetime desc")
                         .getResultList();
    }
        
    public void select()                                              
    {
        message.setRead(true);
    }
        
    public void delete()                                              
    {
        messageList.remove(message);
        em.remove(message);
        message=null;
    }
        
    @Remove                                                           
    public void destroy() {}
        
}
Copy to Clipboard Toggle word wrap

1

@DataModel アノテーションは、 java.util.List タイプの属性を、 javax.faces.model.DataModel インスタンスとして JSF ページに公開します。これにより、各行に対してクリック可能なリンクを持つ JSF <h:dataTable> 中の一覧を使用可能とします。 このサンプルでは、 DataModel は、 messageList という名前のセッションコンテキスト変数で利用可能です。

2

@DataModelSelection アノテーションは Seam にクリックされたリンクに該当する List エレメントをインジェクトするよう指示します。

3

次に @Out アノテーションは選択された値を直接ページに公開します。クリック可能な一覧の行が選択されるたびに Message がステートフル Bean の属性にインジェクトされ、続いて message というイベントコンテキスト変数に アウトジェクト されます。

4

このステートフル Bean は EJB3 拡張永続コンテキスト を持っています。この Bean が存在する限り、クエリで取得されたメッセージは管理状態に留まります。そのため、ステートフル Bean への後続のメッセージ呼び出しは、EntityManager へ明示的な呼び出しを行わずにそのメッセージを更新することができます。

5

初めて JSP ページに移動するとき、 messageList コンテキスト変数には値がありません。@Factory アノテーションは Seam に MessageManagerBean インスタンスを作成し、findMessages() メソッドを呼び出し、値を初期化するよう指示します。findMessages()messagesファクトリメソッド と呼びます。

6

select() アクションリスナーメソッドは、 選択された Message に既読マークを付け、 データベース中のそれを更新します。

7

delete() アクションリスナーメソッドは、 選択された Message をデータベースから削除します。

8

ステートフルセッション Bean の Seam コンポーネントは @Remove とマークされたパラメータを持たないメソッドを定義する 必要があります。Seam コンテキストが終了すると、Seam はステートフル Bean を削除しサーバー側の状態を消去します。

注記

これはセッションスコープの Seam コンポーネントです。 ユーザーログインのセッションと関連付けられ、 ログインセッションからの要求はすべて同じコンポーネントのインスタンスを共有します。 Seam アプリケーションではセッションスコープのコンポーネントは通常、控えめに使用されます。

1.3.1.3. セッション Bean ローカルインタフェース : MessageManager.java

すべてのセッション Bean にビジネスインターフェースがあります。

例1.14 MessageManager.java

@Local
public interface MessageManager {
    public void findMessages();
    public void select();
    public void delete();
    public void destroy();
}
Copy to Clipboard Toggle word wrap
この時点から、ローカルインターフェースはこれらのコードサンプルには表示されなくなります。 Components.xmlpersistence.xmlweb.xmlejb-jar.xmlfaces-config.xmlapplication.xml については前述までのサンプルとほぼ同じなので、 JSP に進みます。

1.3.1.4. ビュー: messages.jsp

この JSP ページは JSF <h:dataTable> コンポーネントを使用した簡単なものです。繰り返しになりますが、この機能も Seam 固有ではありません。

例1.15 messages.jsp

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<html>
  <head>
    <title>Messages</title>
  </head>
  <body>
    <f:view>
      <h:form>
        <h2>Message List</h2>
        <h:outputText value="No messages to display" 
                      rendered="#{messageList.rowCount==0}"/>
        <h:dataTable var="msg" value="#{messageList}" 
                     rendered="#{messageList.rowCount>0}">
          <h:column>
            <f:facet name="header">
              <h:outputText value="Read"/>
            </f:facet>
            <h:selectBooleanCheckbox value="#{msg.read}" disabled="true"/>
          </h:column>
          <h:column>
            <f:facet name="header">
              <h:outputText value="Title"/>
            </f:facet>
            <h:commandLink value="#{msg.title}" 
                           action="#{messageManager.select}"/>
          </h:column>
          <h:column>
            <f:facet name="header">
              <h:outputText value="Date/Time"/>
            </f:facet>
            <h:outputText value="#{msg.datetime}">
              <f:convertDateTime type="both" dateStyle="medium" 
                                 timeStyle="short"/>
            </h:outputText>
          </h:column>
          <h:column>
            <h:commandButton value="Delete" 
                             action="#{messageManager.delete}"/>
          </h:column>
        </h:dataTable>
        <h3><h:outputText value="#{message.title}"/></h3>
        <div><h:outputText value="#{message.text}"/></div>
      </h:form>
    </f:view>
  </body>
</html>
Copy to Clipboard Toggle word wrap
トップに戻る
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2026 Red Hat