Model—form bean
struts是基於Model 2的一種jsp開發架構,struts當然應該有自己的模型(model)。
什麼是模型(model),在mvc模式中,模型用來描述應用程序中的數據。
Struts中的模型(model)是form bean。
我們來看一個form bean實例:
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.*;
public class BookForm extends ActionForm
{
private Book book=new Book();
String title="Ye old Book";
public void setTitle(String title)
{
book.setTitle(title);
}
public String getTitle()
{
return book.getTitle();
}
public void setBook(Book book)
{
this.book=book;
}
public Book getBook()
{
return this.book;
}
public void reset(ActionMapping mapping,HttpServletRequest request)
{
this.book=new Book();
}
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request)
{
ActionErrors errors=new ActionErrors();
if((book.getTitle()==null)||(book.getTitle().length()<3))
{
errors.add("Title",new ActionError("error.book.title"));
}
return errors;
}
}
我們看到,form bean繼承於ActionForm,form bean裏面的屬性就是應用程序要用的數據,每個屬性都有getter和setter方法。Reset方法是當該form bean對應的頁面點擊reset按鈕後執行的動作。而validate方法是對該form bean對應的頁面進行輸入校驗。
Form bean的原則是簡單,只表達jsp要用到的數據即可,不贊成在form bean裏有邏輯操作,邏輯操作應在action bean裏完成。
另外,通過session.setAttribute(“beanName”,bean),request.setAttribute(“beanName”,bean)設置的bean和form bean一樣使用,即可以在網頁上通過struts標記如<bean:write name=”beanName” property=”beanProperty”/>或<html:text name=”beanName” property=”beanProperty”/>取得bean 的屬性,如下例:
List l=new ArrayList();
for(int i=0;i<samyList.size();i++)
{
RadioBean rb=new RadioBean();
rb.setLabel(((SmsAccountMemory)samyList.get(i)).getSmsaccountname());
rb.setValue(((SmsAccountMemory)samyList.get(i)).getSmsaccountname());
l.add(rb);
}
request.setAttribute("accounts",l);
在action bean裏做了上述設置後,我們在名稱爲accounts的bean裏存入了一個List,List裏面的元素是RadioBean,RadioBean有兩個屬性:label和value。
我們看看在頁面上我們怎麼使用這個bean:
<logic:iterate id="account" name="accounts" type="com.tongyou.smsweb.common.RadioBean">
<tr>
<td>
<html:radio property="smsaccountname" value="value" idName="account"/>
<td><bean:write name="account" property="label"/></td>
</tr>
</logic:iterate>
在<logic:iterate>標記裏,我們應用了該bean,name=”accounts”。
每次循環得到的RadioBean,我們放在id=”account”的bean裏面。
Controller—action bean
Struts中的Action類的工作機制 任何的Action類都是org.apache.struts.action.Action的子類。Action子類應該覆寫父類的execute()方法。當ActionForm Bean被創建,並且表單驗證順利通過後,Struts框架就會調用Action類的execute()方法。execute()方法的定義如下: public ActionForward execute(ActionMapping mapping ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException; execute()方法包含一下參數: · ActionMapping:包含了這個Action的配置信息,和struts-config.xml文檔中的 <action>元素對應。 · ActionForm:包含了用戶的表單數據,當Struts框架調用execute()方法時, ActionForm中的數據已通過了表單驗證。 · HttpServletRequest:當前的HTTP請求對象。 · HttpServletResponse:當前的HTTP響應對象。 Action類的execute()方法返回ActionForward對象,他包含了請求轉發路徑信息。
其實,struts的控制器是由系統servlet和action bean共同完成的,由於系統級的控制不用我們操心,這裏我們只講講我們在action bean裏所做的工作。
我們應該在action bean裏所用的工作有:
。往form bean裏賦入初始值
。取得form bean的數據
。行進必要的商業邏輯或顯示邏輯
。網頁轉向
例:
package com.tongyou.smsweb.admin;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.sql.Connection;
import java.util.List;
import com.tongyou.smsweb.common.PageControlFormup;
public class ListTaskAction extends Action{
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
{
try
{
HttpSession session=request.getSession();
UserForm userlogon=(UserForm) session.getAttribute("user");
if(userlogon==null) return (mapping.findForward("logon"));
Connection myconnection=getDataSource(request).getConnection();
TaskManager tm=TaskManager.getInstance(myconnection);
PageControlFormup pcform=(PageControlFormup)form;
uest.getAttribute(mapping.getAttribute());
if(pcform==null) pcform=new PageControlFormup();
List list=tm.getAllTask();
pcform.dowrapped(list);
request.setAttribute(mapping.getAttribute(),pcform);
return (mapping.findForward("ListTask"));
}
catch(Exception e)
{
e.printStackTrace();
return null;
}
}
}
通過上例我們看到, action bean繼承於Action,裏面有一個常用的方法:
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
他的有mapping,用於轉向。
Form,用於取得該action bean對應的form bean,至於這個form bean的類型,看action bean的設置:
<action path="/ListTask"
type="com.tongyou.smsweb.admin.ListTaskAction"
name="PageControlForm"
scope="request" >
我們看到配置裏的name=”PageControlForm”就是該action對應的form bean的名稱,我們在配置裏找到PageControlForm:
<form-bean name="PageControlForm" type="com.tongyou.smsweb.common.PageControlFormup"/>
我們看到該form bean的類型是PageControlFormup,所以在程序中我們有:
PageControlFormup pcform=(PageControlFormup)form;
這樣,我們就取得了該form bean。
return (mapping.findForward("ListTask"));
是action bean執行完後,轉向的網頁,ListTask是轉向名,我們在配置裏可以找到:
<forward name="ListTask"
path="/WEB-INF/jsp/admin/ListTask.jsp"
contextRelative="true"/>
即轉向/WEB-INF/jsp/admin/ListTask.jsp所指的頁面。
在上例中,我們從數據庫裏取得一些數據,賦給action bean對應的form bean,最後轉到對應得頁面進行顯示。
view--jsp
1
<bean:write>是用顯示只讀變量,有兩個參數:name和property。Name裏填form bean的名稱,property裏填form bean裏你想要顯示的屬性。如form bean,user.java裏有我想要顯示的username屬性,則我們這樣表示:<bean:write name=”user” property=”username”/>。
注意:<bean:write>是隻讀的,這意味着我們要不能在action bean裏取得property代表屬性的值。如果我們想取該屬性的值,可用<html:text>,但<html:text>對用戶來說是可讀寫的。如果我們只想用戶對一個屬性只讀,而我們又想在action bean裏取得該屬性的值,我們可以在網頁里加入一個<bean:write>用於給用戶顯示該屬性,再加入一個<html:hidden>用於我們在action bean裏取得該屬性的值,同樣,我們也可以在javascript裏操作該屬性,<bean:write>標記的屬性我們也不能在javascript裏操作。
2
定義網頁的form,action裏是當網頁提交後執行的action bean。如:<html:form action=”/relay”>……</html:form>。
注意:在javascript中,我們要用到form的名稱,那麼對於<html:form action=”/AddTask”>,form的名稱是什麼呢?這要從action裏看:
<action path="/AddTask"
type="com.tongyou.smsweb.admin.AddTaskAction"
name="TasksForm"
scope="request"
input="/WEB-INF/jsp/admin/SpecifyUser.jsp">
</action>
我們看到:action “/AddTask”對應的form bean的名稱是TasksForm,而該action的轉向爲:<forward name="AddTask"
path="/WEB-INF/jsp/admin/AddTask.jsp"
contextRelative="true"/>
則網頁“/WEB-INF/jsp/admin/AddTask.jsp”的form的名爲:TasksForm。
3
邏輯算子最常用的功能是用來處理表格:
<table>
<logic:iterate id=”item” property=”items”>
<tr><td><bean:write name=”item”/></td></tr>
</logic:iterate>
</table>
上例中<logic:iterate>有一個省略參數name,他要求填入bean的名稱,如果省略的話,代表該頁面相對應的form bean。Property是該bean的屬性,是一個集合型變量。Id代表的是集合裏的每一個元素。
如果items={“i1”,”i2”,”i3”,”i4”},則上例的結果爲:
<table>
<tr><td>i1</td></tr>
<tr><td>i2</td></tr>
<tr><td>i3</td></tr>
<tr><td>i4</td></tr>
</table>
如果id代表的是一個對象,則這樣使用:
<table>
<logic:iterate id=”item” name=”ItemForm” property=”items”>
<tr><td><bean:write name=”item” property=”ip1”/></td>
<td><bean:write name=”item” property=”ip2”/></td></tr>
</logic:iterate>
</table>
其中,<logic:iterate>的name參數如果是代表的該頁面對應的form bean,可以省略。
Property代表該bean的一個集合類型的屬性。Id代表的是該集合中的每一個元素,是對象類型的。下面就可以將”item”象對象一樣引用,如item有兩個屬性”ip1”,”ip2”,則有<bean:write name=”item” property=”ip1”/>等等。
4
多選框的使用
<logic:iterate id="item" property="items">
<html:multibox property="selectedItems">
<bean:write name="item"/>
</html:multibox>
<bean:write name="item"/>
</logic:iterate>
在form bean裏,我們有倆個集合屬性items,selectedItems。在action bean裏我們給他們賦值:
items={“i1”,”i2”,”i3”}
selectedItems={}
則上例轉化爲html的結果爲:
<input type="checkbox" name="selectedItems" value="i1">i1
<input type="checkbox" name="selectedItems" value="i2">i2
<input type="checkbox" name="selectedItems" value="i3">i3
我們可以看出,selectedItems是返回結果所存的屬性,而夾在<html:multibox>之間的<bean:write name=”item”/>則給出checkbox中的value屬性的值。
上例中,假如用戶一個都不選,提交該頁面後,selectedItems={},
假設用戶選第一個,提交該頁面後,selectedItems={“i1”}
假如用戶選第三個,提交該頁面後,selectedItems={“i3”}
假如用戶選第一個和第三個,提交該頁面後,selectedItems={“i1”,”i3”}
如果我們在action bean裏賦值:
items={“i1”,”i2”,”i3”}
selectedItems={“i1”}
則上例轉化爲html的結果爲:
<input type="checkbox" name="selectedItems" value="i1" checked=”checked”>i1
<input type="checkbox" name="selectedItems" value="i2">i2
<input type="checkbox" name="selectedItems" value="i3">i3
如果我們在action bean裏賦值:
items={“i1”,”i2”,”i3”}
selectedItems={“i1”
則上例轉化爲html的結果爲:
<input type="checkbox" name="selectedItems" value="i1" checked=”checked”>i1
<input type="checkbox" name="selectedItems" value="i2">i2
<input type="checkbox" name="selectedItems" value="i3" checked=”checked”>i3
如果items是對象的集合,則selectedItems總是簡單類型的集合,其用法爲:
<logic:iterate id="item" property="items">
<html:multibox property="selectedItems">
<bean:write name="item" property=”ip1”/>
</html:multibox>
<bean:write name="item" property=”ip1”/>
,”i3”}
.<html:multibox>
.<logic:iterate>
.<html:form>
.<bean:write>