重温struts
今天公司讓我維護一個老的程序,拿到手后才知道前臺是用struts1。這讓我回想起一年前剛學習struts的時候,那時我還還處于J2EE的懵懂期,寫程序只能照葫蘆畫瓢,現在通過深入的學習MVC,jsp,servlet后才能發現一種struts框架的精妙之處。
struts1中最主要學習的就是actionForm和tag,別的玩過jsp+javabean+servlet的應該不難理解,其中tag由于過多,我也不深入介紹,其實tag中常用的也就幾個,千萬不要被tag的量給嚇倒。在這我主要講下actionForm。
?
首先,瀏覽器將所有的東西都按字符串提交。你可以使用JavaScript校驗來強迫用戶在某個域里面只能輸入數字,或者使用固定的數據格式,但是這也僅是鏡花水月。所有的東西仍然以字符串的方式提交給服務器—而不象準備傳遞給Java方法的二進制對象。
重要的是要記住,這是瀏覽器和HTML 工作的方式。
Web 應用無法控制這些。Struts 之類的框架的存在是使我們必須做的事情做的最好。Struts對HTTP 數據輸入難題的解決方法是使用ActionForm。在象Swing 之類的環境中,數據輸入控件有一個內建的文本緩沖區,可以校驗所輸入的字符。當用戶離開控件,緩沖區可以轉換為二進制類型,可以傳遞給業務層。不幸的是HTTP/HTML 平臺不提供可以緩沖、校驗和輸入轉換的組件。所以Struts 框架提供了一個ActionForm (org.apache.struts.action.ActionForm)類來溝通web瀏覽器和業務對象。ActionForm 提供了想要的緩沖/校驗/轉換機制,我們可以用來保證用戶輸入它們想要輸入的東西。當 HTML 表單提交時,名-值對被Struts 控制器獲取,并應用到ActionForm。ActionForm是一個 JavaBean,有屬性和HTML 表單控件中的域相對應。 Struts 比較ActionForm 屬性的名稱和輸入名-值對的名稱。當匹配時,控制器設置屬性值為相關的輸入域的值。其它的屬性會被忽略。錯過的屬性會保持它們的缺省值(通常是null 或者false)。
?
ActionForm是窗體的對象化表示,它本身其實是個JavaBean,除了標準的getter與setter等方法之外,還提供有reset()、validate()等方法供Struts組件呼叫。
當透過發送請求來到ActionServlet后,ActionServlet會從ActionMapping對象中得知所使用的ActionForm對象,這是在struts-config.xml中設定的,如果所需的ActionForm還不存在就生成一個,之后一直使用它,ActionMapping與ActionForm對象會被當作參數傳遞給Action對象。
在Struts 1.1中,ActionForm生成之后,會執行RequestProcessor的processPopulate()方法,首先它會呼叫 ActionForm的reset()方法,您可以在當中作一些重清ActionForm屬性的動作,然而窗體的參數值會與ActionForm的 setter進行比對,如果有名稱符合的就將窗體的參數值設定給對應的屬性。
我們透過繼承ActionForm類別來使用它,下面是一個簡單的例子:
package onlyfun.caterpillar; import javax.servlet.http.*;import org.apache.struts.action.*; public class UserForm extends ActionForm { protected String name; protected String password; public void setName(String name) { this.name = name; } public void setPassword(String password) { this.password = password; } public String getName() { return name; } public String getPassword() { return password; } public void reset(ActionMapping mapping, HttpServletRequest req) { name = null; password = null; }}???
ActionForm類別編譯后必須放置于WEB-INF中,并包括套件階層,我們必須在struts-config.xlm中定義Action對象使用哪一個ActionForm對象:
?
<struts-config> ??? <form-beans> ??????? <form-bean ??????????? name="userForm" ??????????? type="onlyfun.caterpillar.UserForm"/> ??? </form-beans> ??????????????????????????? ???????????????????????????????????????????????????? ??? <global-forwards> ??????? <forward ??????????? name="welcome" ??????????? path="/Welcome.do"/> ??? </global-forwards> ??????????????????????????????????????????????????????????????????????????????? ??? <action-mappings> ??????? <action ??????????? path="/Welcome" ??????????? type="org.apache.struts.actions.ForwardAction" ??????????? parameter="/pages/Welcome.jsp"/> ??????????????????????????????????????????????????????????????????????????????? ???? ??? <action ??????????? path="/LoginAction" ??????????? type="onlyfun.caterpillar.LoginAction" ??????????? name="userForm"> ??????????? <forward ??????????????? name="greeting" ??????????????? path="/pages/greeting.jsp"/> ??????? </action> ??? </action-mappings> ??? <message-resources parameter="resources.application"/> </struts-config>?
在這個例子中,<form-bean>標簽定義了所使用的ActionForm對象及 名稱,而在<action>標簽的設定中,LoginAction指定了userForm作為其所使用的ActionForm,我們的 LoginAction類別如下: import javax.servlet.http.*;import org.apache.struts.action.*; public class LoginAction extends Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { String name = ((UserForm) form).getName(); String password = ((UserForm) form).getPassword(); if(name.equals("caterpillar") && password.equals("1234")) { request.setAttribute("valid_user", form); return mapping.findForward("greeting"); } return mapping.findForward("welcome"); }} ActionForm被作為參數傳遞至execute()方法,我們必須轉換為其原來的形態 UserForm,這樣才可以取出當中的屬性值,在驗證使用者的名稱與密碼無誤后,我們查找greeting的ActionForward對象并傳回,這 會使得ActionServlet將請求forward至greeting.jsp: <%@ taglib uri="/tags/struts-bean" prefix="bean" %><%@ taglib uri="/tags/struts-html" prefix="html" %><%@ taglib uri="/tags/struts-logic" prefix="logic" %><%@page contentType="text/html; charset=Big5"%><html:html locale="true"><head><title><bean:message key="welcome.title"/></title><html:base/></head><body bgcolor="white"> <logic:present scope="request" name="valid_user"> <bean:write name="valid_user" property="name"/>您好,這是您的神秘禮物!</logic:present> <logic:notPresent scope="request" name="valid_user"> <html:link forward="welcome">請先登入</html:link></logic:notPresent> </body></html:html> <html:form>指定的LoginAction必須在struts-config.xml 中有定義,<html:text>與<html:password>會取出對應的ActionForm對象中對應的屬性值,如果 使用者填寫的內容不正確而被送回Welcome.jsp,使用者將可以看到先前所填寫的值,如果不想顯示先前所填寫的值,則將<html: text>與<html:password>的redisplay屬性設定為false即可,這幾個Struts卷標必須與Action對象及ActionForm對象搭配使用。
接下來您可以測試一下程序,連上http://localhost:8080/HelloStruts/,如果您填寫了正確的窗體字段并送出,則結果會如下: <html lang="zh"> <head> <title>哈啰!Struts!</title> <base href="http://localhost:8080/HelloStruts/pages/greeting.jsp"> </head> <body bgcolor="white"> ??? caterpillar您好,這是您的神秘禮物! </body> </html> ActionForm在Struts中是屬于視圖組件的一部份,它是窗體的對象化窗體,窗體的參數會自動設定給 ActionForm,無法對應的就加以忽略,您可以定義validate()方法來驗證窗體設定的內容,這在下一個主題中將加以說明,在 ActionForm中您可以填入窗體值,作一些適當的值轉換,進行基本的數據驗證,ActionForm是窗體數據發送至應用程序前的緩沖區,在某些程 度上,它是應用程序的防火墻,您可以在ActionForm中避免不正確或不安全的數據進入應用程序。
綜合一下,ActionForm擔任以下的幾個職責:
*窗體字段的耕耘者
*數據的緩沖區
*數據的驗證
*進行屬性值的轉換
*應用程序防火墻
轉載于:https://www.cnblogs.com/hainange/archive/2009/07/23/6153113.html
總結
- 上一篇: Schmid Telecom选择Stor
- 下一篇: 剖析Linux系统启动过程(二)