seam使JSF和EJB3整合的天衣無縫,使得頁面和後臺代碼實現了組件化,並且實現了針對客戶一次操作會話管理。使用seam開發減少了大部分xml文件的配置。大量的註解封裝了強大的功能,至少減少了30%的代碼量。強大的功能,僅需少量的代碼實現。
本文描述頁面流程的開發過程,演示一個頁面流的長會話功能。使用三個頁面,輸入表單信息,在最後的頁面統一將三個頁面所添加的內容統一保存到數據表內。
具體細節如下:
1 定義一個實體有7個屬性,分別爲主鍵、頁面1標題、頁面1內容、頁面2標題、頁面2內容、頁面3標題、頁面3內容。
2 基於eclipse的jbpm可視化插件,編寫jpdl流程定義語言。
3 定義有狀態的session bean。用於實現業務邏輯,這裏主要用於開始頁面流程、頁面跳轉和數據持久化。
4 定義三個xhtml頁面,用於表單錄入與提交。
5 在War目錄下定義components.xml文件,加載流程定義描述,這裏雖然使用jbpm但頁面流不會持久化到數據庫當中,頁面流只負責頁面級的頁面流轉。
6 配置page.xml 實現頁面導航。
具體代碼如下:
1 實體WorkFlowDoc
/*******************************************************************************
* 文件名:WorkFlowDoc.java<br>
* 版本: <br>
* 描述: <br>
* 版權所有: <br>
* //////////////////////////////////////////////////////// <br>
* 創建者: 沙振中 <br>
* 創建日期: May 12, 2009 <br>
* 修改者: <br>
* 修改日期: <br>
* 修改說明: <br>
******************************************************************************/
package org.shaneseam.entitybean;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.jboss.seam.annotations.Name;
@Entity
@Name("workFlowDoc")
public class WorkFlowDoc {
Long workFlowId;
String workOneTitle;
String workOneContext;
String workTwoTitle;
String workTwoContext;
String workThreeTitle;
String workThreeContext;
public WorkFlowDoc()
{}
/**
* @return the workFlowId
*/
@Id @GeneratedValue
public Long getWorkFlowId() {
return workFlowId;
}
/**
* @param workFlowId the workFlowId to set
*/
public void setWorkFlowId(Long workFlowId) {
this.workFlowId = workFlowId;
}
/**
* @return the workOneTitle
*/
public String getWorkOneTitle() {
return workOneTitle;
}
/**
* @param workOneTitle the workOneTitle to set
*/
public void setWorkOneTitle(String workOneTitle) {
this.workOneTitle = workOneTitle;
}
/**
* @return the workTwoTitle
*/
public String getWorkTwoTitle() {
return workTwoTitle;
}
/**
* @param workTwoTitle the workTwoTitle to set
*/
public void setWorkTwoTitle(String workTwoTitle) {
this.workTwoTitle = workTwoTitle;
}
/**
* @return the workTwoContext
*/
public String getWorkTwoContext() {
return workTwoContext;
}
/**
* @param workTwoContext the workTwoContext to set
*/
public void setWorkTwoContext(String workTwoContext) {
this.workTwoContext = workTwoContext;
}
/**
* @return the workThreeTitle
*/
public String getWorkThreeTitle() {
return workThreeTitle;
}
/**
* @param workThreeTitle the workThreeTitle to set
*/
public void setWorkThreeTitle(String workThreeTitle) {
this.workThreeTitle = workThreeTitle;
}
/**
* @return the workThreeContext
*/
public String getWorkThreeContext() {
return workThreeContext;
}
/**
* @param workThreeContext the workThreeContext to set
*/
public void setWorkThreeContext(String workThreeContext) {
this.workThreeContext = workThreeContext;
}
/**
* @return the workOneContext
*/
public String getWorkOneContext() {
return workOneContext;
}
/**
* @param workOneContext the workOneContext to set
*/
public void setWorkOneContext(String workOneContext) {
this.workOneContext = workOneContext;
}
}
2 PageFlowSwitch.jpdl.xml頁面流程定義文件
<?xml version="1.0"?>
<pageflow-definition
xmlns="http://jboss.com/products/seam/pageflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.com/products/seam/pageflow http://jboss.com/products/seam/pageflow-2.1.xsd"
name="pageflowswitch">
<start-state name="start">
<transition to="page1"/>
</start-state>
<page name="page1" view-id="/pageflow/page1.xhtml">
<redirect/>
<transition name="next" to="toDecision"/>
</page>
<decision name="toDecision" expression="#{pageFlowAction.validInfo}">
<transition name="true" to="page2"/>
<transition name="false" to="page1">
</transition>
</decision>
<page name="page2" view-id="/pageflow/page2.xhtml"
no-conversation-view-id="/pageflow/page1.xhtml">
<redirect/>
<transition name="prev" to="page1"/>
<transition name="next" to="page3"/>
</page>
<page name="page3" view-id="/pageflow/page3.xhtml"
no-conversation-view-id="/pageflow/page1.xhtml">
<redirect/>
<transition name="prev" to="page2"/>
<transition name="next" to="complete">
<action expression="#{pageFlowAction.savePage}"/>
</transition>
</page>
<page name="complete" view-id="/pageflow/complete.xhtml"
no-conversation-view-id="/pageflow/page1.xhtml">
<end-conversation/>
<redirect/>
</page>
</pageflow-definition>
3 PageFlowAction的組件類
/*******************************************************************************
* 文件名:PageFlow.java<br>
* 版本: <br>
* 描述: <br>
* 版權所有: <br>
* //////////////////////////////////////////////////////// <br>
* 創建者: 沙振中 <br>
* 創建日期: May 11, 2009 <br>
* 修改者: <br>
* 修改日期: <br>
* 修改說明: <br>
******************************************************************************/
package org.shaneseam.action;
import javax.annotation.Resource;
import javax.ejb.Remove;
import javax.ejb.SessionContext;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.shaneseam.action.inte.PageFlow;
import org.shaneseam.entitybean.PageFlowSwitch;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.contexts.Context;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.security.Identity;
@Stateful
@Name("pageFlowAction")
public class PageFlowAction implements PageFlow {
@PersistenceContext
EntityManager em;
@Resource
SessionContext ctx;
@In
Context sessionContext;
@In(create=true)
@Out
PageFlowSwitch pageFlowSwitch;
@In
FacesMessages facesMessages;
@In Identity identity;
@Begin(nested=true, pageflow="pageflowswitch")
public void startFlow() {
}
public boolean isValidInfo() {
boolean ok = true;
// custom if and else
return ok;
}
@End
public String savePage() {
try {
em.persist(pageFlowSwitch);
// sessionContext.set("pageFlowSwitch", pageFlowSwitch);
return "success";
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Remove
public void destroy() {
}
}
4 頁面page1.xhtml, page2.xhtml, page3.xhtml, complete.xhtml
4.1 page1.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 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">
<body>
<div >
This is page1
<h:form id="NewAccountForm">
<table border="0">
<tr>
<td>page1 title</td>
<td>
<h:inputText id="pageTitle" required="true" value="#{pageFlowSwitch.pageOneTitle}"></h:inputText>
</td>
</tr>
<tr>
<td>page1 context</td>
<td>
<h:inputText id="pageContext" required="true" value="#{pageFlowSwitch.pageOneContext}"></h:inputText>
</td>
</tr>
</table>
<h:commandButton id="ContinueButton" action="next" value="Continue" />
</h:form>
</div>
</body>
</html>
4.2 page2.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 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">
<body>
This is page2.
<h:form id="NewAccountForm">
<table border="0">
<tr>
<td>page2 title</td>
<td>
<h:inputText id="pageTitle" required="true" value="#{pageFlowSwitch.pageTwoTitle}"></h:inputText>
</td>
</tr>
<tr>
<td>page2 context</td>
<td>
<h:inputText id="pageContext" required="true" value="#{pageFlowSwitch.pageTwoContext}"></h:inputText>
</td>
</tr>
</table>
<ui:remove><h:commandButton id="BackButton" action="prev" value="Back" /></ui:remove>
<h:commandButton id="ContinueButton" action="next" value="Continue" />
</h:form>
</body>
</html>
4.3 page3.xhtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html 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">
<body>
<h:form id="NewAccountForm">
<table border="0">
<tr>
<td>page3 title</td>
<td>
<h:inputText id="pageTitle" required="true" value="#{pageFlowSwitch.pageThreeTitle}"></h:inputText>
</td>
</tr>
<tr>
<td>page3 context</td>
<td>
<h:inputText id="pageContext" required="true" value="#{pageFlowSwitch.pageThreeContext}"></h:inputText>
</td>
</tr>
</table>
<h:commandButton id="SubmitNewCustomerButton" action="next" value="newpage" />
</h:form>
</body>
</html>
4.4 complete.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>completel.xhtml</title>
<meta http-equiv="keywords" content="enter,your,keywords,here" />
<meta http-equiv="description" content="A short description of this page." />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<!--<link rel="stylesheet" type="text/css" href="styles.css">-->
</head>
<body>
<p>
This is my XHTML page.
</p>
</body>
</html>
5 components.xml
<bpm:jbpm>
<bpm:pageflow-definitions>
<value>PageFlowSwitch.jpdl.xml</value>
</bpm:pageflow-definitions>
</bpm:jbpm>