struts2的開發(fā)規(guī)范與技巧
Struts2的前景還是穩(wěn)健的,使用的人數在不斷的增加。參看struts 2依然堅挺 Seam前景不明
但基于Struts2的開發(fā),如果沒有足夠的經驗和規(guī)范做支撐,并不能帶來還多的好處,如果失控,一樣和JSP+servlet泛濫,這一點需要警示。
1).Action類及Action Name的命名規(guī)范
Action類的后綴統(tǒng)一加上"Action",
Action的Name與類的名稱保持一致,但不要"Action"的后綴。
這樣是為了通過Action的調用url, 很方便的找到Action類。
1 action name="searchKnowledge"
2 class="com.demo.search.action.SearchKnowledgeAction">
3 result name="search">/demo/search.jspresult>
4 action>
如上,看到/searchKnowledge.action,就可以很清楚的知道類是SearchKnowledgeAction了。很多人不注重這一點,開發(fā)調試中,每次都要笨拙的看struts.xml文件。
2).每個項目都必須至少有一個公用的Action類,GenericAction
完成的功能如下:
1.獲取、注入request
2.獲取、注入Session
3.錯誤頁面跳轉
4.獲取在線用戶和會員的信息(個人信息、權限、角色等)
5.注入類型轉換的格式轉換類,如日期類型轉換:ConvertUtils.register(new DateConverter(), Date.class);
6.獲取系統(tǒng)配置信息,如公用變量(如配置路徑等)
7.對于request參數的處理等
8.其他可擴展的操作
3).擅長使用Dispatch的模式
有人說Action,不就是Dispatch的延伸嗎,其實還可以做的更好。
這個典型的模式如下:
1.頁面表單的Hidden參數中,就是一個ID,如queryID="queryKnowledges". Action="/paginate.action"
2.PaginateAction的模板如下
1private String queryID;
2 public String execute() {
3 //獲得Service的接口
4 //根據queryID調用Ibatis分頁查詢方法
5 return queryID; //這一點,就是動態(tài)跳轉,在Action不明確注明"success"之類的跳轉名稱。
6 }
3.在struts.xml中進行配置與queryID想對應:
1 action name="paginate"
2 class="com.gehc.util.pagination.PaginateAction">
3 result name="queryKnowledges">
4 /demo/knowledgeList.jsp
5 result>
6
7 result name="queryIssue">
8 /pm/issue/allIssue.jsp
9 result>
10
11 action>
實戰(zhàn)代碼如下:
4).配置文件的目錄結構
5).不斷的提煉公用的Action,并放在一個package中:
如上傳、下載、異常處理、excel數據錄入、過濾器(filter)、截取器(inteceptor)等等
6).將一個模塊中的Action放置在一起
7).擅與使用redirect來保持request參數.
使用redirect一樣可以將request參數傳遞到下一頁面中,不需要使用session.
viewPost?postid=${postid}
public String execute() throws Exception {
//一些處理……
name=xiaowang ; //給要傳遞的參數賦值
return SUCCESS; //默認頁面
//return "redirect_1" ; //重定向(不帶參數) showInfo.do
//return "redirect_2" ; //重定向(帶固定參數yangzi) showInfo.do?name=yangzi
//重定向(帶動態(tài)參數,根據struts.xml的配置將${name}賦值為xiaowang)最后為 showInfo.do?name=xiaowang
// return "redirect_3" ;
//return "redirect_4" ; //這個是重定向到 一個action
}
action name="login" class="LoginAction">
result name="success" type="velocity">/pages/logok.vmresult>
result name="redirect_1" type="redirect">showInfo.doresult>
result name="redirect_2" type="redirect">showInfo.do?name=yangziresult>
result name="redirect_3" type="redirect">showInfo.do?name=${name}result>
result name="redirect_4" type= "redirect">
param name="actionName">showInfoparam>
param name="name">${name}param>
result>
action>
8)靈活使用chain模式,來編寫簡短而高度重用的Action,把相關的幾個action連接起來,共同完成一個功能。
同一個Chain的多個action間數據的傳遞非常方便,由于處于chain中的action屬于同一個http請求,共享一個ActionContext,故可以在上下文中獲取,在頁面上可以直接使用,上一個Action的成員變量。
1<action name="step1" class="test.Step1Action">
2 <result name="success" type="chain">step2.action</result>
3</action>
4
5<action name="step2" class="test.Step2Action">
6 <result name="success">finish.jsp</result>
7</action>
9) 編寫簡潔而高度重用的Action的另一個方法,就是將頁面的渲染,格式轉換的邏輯,抽取出來,自定義成Result。
官方的Result
Chain Result - 用于 Action Chaining
Dispatcher Result - 用于 JSP 整合
FreeMarker Result - 用于 FreeMarker 整合
HttpHeader Result - 用于控制特殊的HTTP行為
JasperReports Result - 用于 JasperReports 整合
Redirect Result - 用于直接跳轉到例外的URL
Redirect Action Result - 用于直接跳轉到另外的action
Stream Result - 用于向瀏覽器返回一個InputStream (一般用于文件下載)
Velocity Result - 用于 Velocity 整合
XSL Result - 用于 XML/XSLT 整合
PlainText Result - 用于顯示某個頁面的原始的文本 (例如 jsp, html 等)
Json Result
JFreechart Result
10) 明確Action類不要超長,如不要超過500行代碼。
很多人為了偷懶,喜歡在一個Action中,不斷的添加方法,而不管這些方法與Action的語義是否符合,到底是多個Action,還是多個方法,在開發(fā)過程中,還是要注重這些方法是否與創(chuàng)建Action類的目的、語義保持一致。