這篇博客我們來說一下Struts的主要組成我們,通過前幾篇博客,我們知道這個框架最重要的幾個步驟: 獲取路徑、封裝表單、獲取轉向列表、轉向邏輯處理、轉向,與此對應的是:ActionServlet、ActionForm、 ActionMapping、Action、ActionForward。
ActionServlet
這個在上篇博客已經說明,可以訪 問《 預加載ActionServlet》。
ActionForm
ActionForm的主要作用是對表單數據進行封裝,這 個.NET開發中的實體類有些類似,它的使用有以下限制:ActionForm中的get/set屬性名必須和表單字段一致 ;必須繼承自org.apache.struts.action.ActionForm。
ActionForm除了封裝數據意外,還可以進行對 數據進行校驗、組裝前初始化屬性,當然這分別需要實現validate和reset函數。
ActionForm轉換器
它還可以數據自動進行邏輯轉換,使用的是bean-utils的轉換器,這個在上篇博客中提到了一次,它 位於ActionServlet中的initOther()中,如下:
if (convertNull) { ConvertUtils.deregister(); ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class); ConvertUtils.register(new BigIntegerConverter(null), BigInteger.class); ConvertUtils.register(new BooleanConverter(null), Boolean.class); ConvertUtils.register(new ByteConverter(null), Byte.class); ConvertUtils.register(new CharacterConverter(null), Character.class); ConvertUtils.register(new DoubleConverter(null), Double.class); ConvertUtils.register(new FloatConverter(null), Float.class); ConvertUtils.register(new IntegerConverter(null), Integer.class); ConvertUtils.register(new LongConverter(null), Long.class); ConvertUtils.register(new ShortConverter(null), Short.class); }
這個代碼段的作用是將轉換器初始化到一個map中,它們都實現了Convert接口的方法:
public Object convert(Class type, Object value);
如boolean類型的轉換器,代碼如 下:
以boolean的轉換器為例 public Object convert(Class type, Object value) { if (value == null) { if (useDefault) { return (defaultValue); } else { throw new ConversionException("No value specified"); } } if (value instanceof Boolean) { return (value); } try { String stringValue = value.toString(); if (stringValue.equalsIgnoreCase("yes") || stringValue.equalsIgnoreCase("y") || stringValue.equalsIgnoreCase("true") || stringValue.equalsIgnoreCase("on") || stringValue.equalsIgnoreCase("1")) { return (Boolean.TRUE); } else if (stringValue.equalsIgnoreCase("no") || stringValue.equalsIgnoreCase("n") || stringValue.equalsIgnoreCase("false") || stringValue.equalsIgnoreCase("off") || stringValue.equalsIgnoreCase("0")) { return (Boolean.FALSE); } else if (useDefault) { return (defaultValue); } else { throw new ConversionException(stringValue); } } catch (ClassCastException e) { if (useDefault) { return (defaultValue); } else { throw new ConversionException(e); } } }
可以看到它轉換的類型有限,如果我想轉換其它的類型怎麼辦?還好,這裡提供了自定義轉換 器的功能,具體見博客《自定義轉換器》。
動態ActionForm
它是以配置文件的形式存在的,例 如在struts-config中配置:
<form-beans> <form-bean name="dynaForm" type="org.apache.struts.action.DynaActionForm" > <form-property name="username" type="java.lang.String" /> <form-property name="age" type="java.lang.Integer" /> </form-bean> </form-beans>
需要注意的是動態ActionForm的讀取方式稍有不同:
<body> 用戶名:${dynaForm.map.username }; 注意它的獲取方式 年 齡:${dynaForm.map.age } </body>
ActionForward
轉向和重定向
struts默認的mapping.findForward是轉 發,如果需要重定向,則需要添加redirect屬性:
<forward name="login" path="/login.jsp" redirect="true"/>
頁面保護
一般情況下我們可以通 過更改url路徑直接訪問某一個jsp界面,有時這樣是沒必要且不安全的,但是如果將其放到web-inf文件夾下 ,則不可以通過url直接訪問,可以做為限制jsp訪問的一種方法。
動態修改
struts配置文件啟 動就加載到內存中,運行期不允許修改,所以不能使用forward.findForward().setRedirect 的值,如果想使 用代碼實現跳轉可以采用以下方式:
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { response.sendRedirect(request.getContextPath()+"/login.jsp"); return null; }
和
@Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { int page=Integer.parseInt(request.getParameter("page").toString()); ActionForward af=null; af.setPath("/"+page+".jsp"); return af; }
雖然可以使用,但是這會大大降低代碼的靈活性和可擴展性,所以不推薦使用。
Action
Action就是核心邏輯控制器,它主要負責獲取參數、調用Model、轉向三個方面。
ForwardAction
Action的子類,作用與action中的forward標簽類似,但是二者在處理的時候 還是有區別的,執行RequestProcessor的
// Process a forward or include specified by this mapping if (!processForward(request, response, mapping)) { return; }
時,如果使用forward屬性時,會直接return,而使用ForwardAction時會繼續執行。
DispatchAction
詳見博客《詳解DispatchAction》
ActionMapping unknown屬性
在配置文件中添加unknown屬性,即在發生404錯誤時,自動跳轉到unknown的頁面 ,例如:
<action forward="/unknown.jsp" unknown="true"></action>
input屬性
input屬性的意思是在struts中配置action 時,加入input,這樣的作用是省去了一個forward標簽,例如
注意使用input屬性時,和以前 的跳轉稍有不同:
總結
文章至此, Struts1的基本組成部分已經講解完畢,其它諸如國際化、異常處理、標簽庫等都是實用性的知識,在此不再 說明。