此内容没有您所选择的语言版本。

1.3. Clickable lists in Seam: the messages example


Clickable lists of database search results are a vital part of any online application. Seam provides special functionality on top of JSF to make it easier to query data with EJB-QL or HQL, and display it as a clickable list using a JSF <h:dataTable>. The messages example demonstrates this functionality.

1.3.1. Understanding the code

The message list example has one entity bean (Message), one session bean (MessageListBean), and one JSP.

1.3.1.1. The entity bean: Message.java

The Message entity defines the title, text, date and time of a message, and a flag indicating whether the message has been read:

Example 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. The stateful session bean: MessageManagerBean.java

As in the previous example, this example contains a session bean (MessageManagerBean) which defines the action listener methods for both of the buttons on our form. As in the previous example, one of the buttons selects a message from the list and displays that message; the other button deletes a message.
However, MessageManagerBean is also responsible for fetching the list of messages the first time we navigate to the message list page. There are various ways for users to navigate to the page, not all of which are preceded by a JSF action. (Navigating to the page from your favorites will not necessarily call the JSF action, for example.) Therefore, fetching the message list must take place in a Seam factory method, instead of in an action listener method.
We want to cache the list of messages in memory between server requests, so we will make this a stateful session bean.

Example 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

The @DataModel annotation exposes an attributes of type java.util.List to the JSF page as an instance of javax.faces.model.DataModel. This allows us to use the list in a JSF <h:dataTable> with clickable links for each row. In this case, the DataModel is made available in a session context variable named messageList.

2

The @DataModelSelection annotation tells Seam to inject the List element that corresponded to the clicked link.

3

The @Out annotation then exposes the selected value directly to the page. So every time a row of the clickable list is selected, the Message is injected to the attribute of the stateful bean, and then subsequently outjected to the event context variable named message.

4

This stateful bean has an EJB3 extended persistence context. The messages retrieved in the query remain in the managed state as long as the bean exists, so any subsequent method calls to the stateful bean can update them without needing to make any explicit call to the EntityManager.

5

The first time we navigate to the JSP page, there will be no value in the messageList context variable. The @Factory annotation tells Seam to create an instance of MessageManagerBean and invoke the findMessages() method to initialize the value. We call findMessages() a factory method for messages.

6

The select() action listener method marks the selected Message as read, and updates it in the database.

7

The delete() action listener method removes the selected Message from the database.

8

All stateful session bean Seam components must define a parameterless method marked @Remove that Seam uses to remove the stateful bean when the Seam context ends, and clean up any server-side state.

Note

This is a session-scoped Seam component. It is associated with the user log in session, and all requests from a log in session share the same instance of the component. Session-scoped components are usually used sparingly in Seam applications.
All session beans have a business interface:

Example 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
From this point, local interfaces are no longer shown in these code examples. Components.xml, persistence.xml, web.xml, ejb-jar.xml, faces-config.xml and application.xml operate in a similar fashion to the previous example, and go directly to the JSP.

1.3.1.4. The view: messages.jsp

The JSP page is a straightforward use of the JSF <h:dataTable> component. Once again, these functions are not Seam-specific.

Example 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

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat