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>