模塊配置 1. Struts配置文件定義 對于系統(tǒng)中的某個模塊,需要在開發(fā)前定義該模塊的配置,該struts的配置文件命名為: struts-config-xxx.xml xxx為模塊的小寫英文名或縮寫,如:struts-config-sysman.xml 注意:中間為“-”,而不是“_”連接符 統(tǒng)一保存在“WEB-INF\xml”文件夾下,并需要在web.xml中添加相應(yīng)的配置文件 地址,具體如下例: … <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml, /WEB-INF/xml/struts-config-pages.xml,/WEB-INF/xml/struts-config-sysman.xml</param-value> </init-param> … 注意:需要用“,”連接符隔開各個配置文件名 另外,所有的靜態(tài)jsp需要通過配置文件定義其“.do”形式的訪問,保存在 struts-config-pages.xml文件中,內(nèi)容如下例: … <!--主頁轉(zhuǎn)向--> <action path="/main" type="org.apache.struts.actions.ForwardAction" parameter="/main.jsp"/> … 2. Tiles配置文件定義 系統(tǒng)的框架配置文件為tiles-defs_zh_CN.xml(通過.properties屬性文件支持國際化應(yīng)用,默認(rèn)是tiles-defs.xml),模塊的框架結(jié)構(gòu)需要定義在里面,如下例: … <!-- 定義默認(rèn)首頁 --> <definition name="default.frame" path="/layouts/defaultLayout.jsp"> <put name="title" value="歡迎進(jìn)入電信經(jīng)營分析系統(tǒng)" /> <put name="header" value="/top.jsp" /> <put name="body" value="default.body" /> <put name="footer" value="/buttom.jsp" /> </definition> <!-- 定義默認(rèn)首頁的body --> <definition name="default.body" path="/layouts/main.jsp" > <put name="logon" value="/logon.jsp" /> <put name="date" value="/layouts/date.jsp" /> <put name="linkSite" value="/layouts/link.html" /> </definition> … 框架命名規(guī)范按“系統(tǒng)(子系統(tǒng)).功能模塊.頁面模塊”,如上面的“default.frame” 在struts-config-pages.xml文件中的設(shè)置的頁面action可以這樣寫: <action path="/main" type="org.apache.struts.actions.ForwardAction" parameter=" default.frame "/> 這樣就不必單獨(dú)寫一個tiles:insert的頁面,如下: <tiles:insert definition="vip.warn.day" flush="true" /> 3. 模塊中的注釋 不 但需要在程序中添加必要的注釋,在定義配置文件的時候也必須需要添加相應(yīng)注釋,主要是在struts-config-xxx.xml和tiles- defs_zh_CN.xml這些文件中添加注釋,要把a(bǔ)ction或配置模塊的功能解釋清楚,放在配置項(xiàng)的前面,參見上面的配置文件 4. 對于配置文件的編輯 不能使用Jbuilder里面的xml編輯功能,因?yàn)镴B會自動地改變xml里面的編碼和內(nèi)容,因此,對xml配置文件的編輯,要使用編輯軟件,如UE等 事件定義 事件對應(yīng)的類主要有Action、ActionForm,還有jsp中提交的“.do”定義,以及頁面動作的提交,以login登錄為例: 1. 類的命名定義(首字母需大寫) 形式為“動作名+Action/Form” 如:LoginAction.class、LoginForm.class 2. 頁面地址定義(首字母需小寫) 如果有兩個單詞以上,第二個單詞首字母大寫,依此類推 形式為“動作名” 如:login.do或loginSys.do jsp文件命名也按此規(guī)范 3. 頁面動作定義 因?yàn)閖sp頁面中的Form對應(yīng)ActionForm,其本身有action這個屬性,所以頁面動作如果定義也為action,會引起不必要的麻煩,所以,把頁面動作統(tǒng)一定義為“act”, 如需要編輯某條記錄,地址如下: “/editRecord.do?act= Edit” 如需要刪除,地址如下: “/editRecord.do?act=Delete” 4. 對于菜單和操作事件觸發(fā)的控制機(jī)制 由于系統(tǒng)中的菜單和操作都是由“.do”形式向服務(wù)端發(fā)請求的,因此需要一套機(jī)制來控制哪些是對菜單的事件請求,哪些是對操作的事件請求; 我們在系統(tǒng)中引入了Filter過濾器,對所有請求進(jìn)行控制,以及判斷用戶是否登錄和是否有對資源(菜單等)訪問權(quán)限等; 約定: jsp頁面上對于系統(tǒng)中菜單的請求都是“GET”方法,對于操作的Action都是“POST”方法; 有了這樣的約定,在Filter中先判斷request的請求方法,如果是“GET”方法,則認(rèn)為是對菜單的請求,所以去“菜單表”根據(jù)請求地址讀取相應(yīng)的記錄,并讀取用戶的權(quán)限表,判斷用戶的菜單權(quán)限; 如果是“POST”的方法,則認(rèn)為是對操作的請求,并提取request中的“act”動作,進(jìn)行對用戶的權(quán)限點(diǎn)的判定。 參數(shù)信息獲取 1. 公共參數(shù)信息通過Plugin方式在Web服務(wù)啟動時將變量放入application中,使得在任何需要該變量的jsp中都可以調(diào)用; 方式如下: public void setServletContext(ActionServlet actionServlet) { try { ServletContext sc = actionServlet.getServletContext(); //SysInitPwd sc.setAttribute(Constants.SYS_INIT_PWD,SelectLists.getSysConfig("PWDINIT")); … 在action等程序中的調(diào)用方式: getServlet().getServletContext().getAttribute(“…”); 2. 對于頁面上需要展示的數(shù)據(jù)盡量存放在request這個范圍里,可以減輕服務(wù)器端內(nèi)存負(fù)載,方式如下: //調(diào)用員工處理類 StaffDeal sd=new StaffDeal(); //根據(jù)員工狀態(tài)查詢員工 ArrayList al=sd.qryStaff(strState); //放入request request.setAttribute("staffInfo",al); 3. 私有的或需要根據(jù)用戶的屬性來獲取參數(shù)信息的,可以在tiles的定義中使用“controlClass=xxx”這個方式獲取,配置如下例: <definition name="vip.welcome" path="/vip/welcome.jsp" controllerClass="viptx.logic.vip.welcomeAction" /> 需implements Controller中的perform方法,代碼如下例: public void perform(ComponentContext componentContext, HttpServletRequest request, HttpServletResponse response, ServletContext servletContext) throws IOException,ServletException { HttpSession session = request.getSession(); // Get current session. User user = (User) session.getAttribute(Constants.USER_KEY); if (user == null) { return null; } String uid = user.getUserid(); String sql = "select userid,content from ti_salutatory where userid=‘"+uid+"‘"; try { … } catch (Exception ex) { throw new ServletException(ex.getMessage()); } } 4. 對于后臺出錯信息在前臺頁面顯示的技巧 首先在properties配置“message.common={0}” 然后在Action類中使用ActionErrors或ActionMessages時,方法如下: … ActionMessages ams = new ActionMessages(); //例外處理 Try{ … } catch (Exception ex) { ex.printStackTrace(); ams.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("message.common", ex.getMessage())); } finally { if (!ams.isEmpty()) { saveMessages(request, ams); } } … 在jsp頁面中使用方法如下: <html:messages id="msg" message="true"> <font color="red"><bean:write name="msg"/></font> </html:messages> 如果有后臺的messages產(chǎn)生,前臺頁面就可以出現(xiàn)報錯信息 5. 系統(tǒng)配置文件 系統(tǒng)參數(shù)如數(shù)據(jù)庫連接等在sysConfi.xml文件中配置,存放在“WEB-INF/xml”文件夾下,請參見該文件。 開發(fā)規(guī)范和公用方法 關(guān)于java的開發(fā)規(guī)范參見《Java 編程規(guī)范.doc》,這里僅給出用struts開發(fā)中一些的規(guī)范: 1. java文件存放按業(yè)務(wù)邏輯劃分,并用模塊作為包名的形式,如:telecombi.logic.sysman.security 包名都為小寫形式 所有的Action和ActionForm都存放在同一包下,便于管理,不要跨包調(diào)用 2. 所有ActionForm中的屬性均為“首單詞小寫+第二個單詞首字母大寫+…”的形式,如:staffId、staffName,不允許使用“_”為單詞連接符 3. 需要驗(yàn)證的頁面,均需要客戶端和服務(wù)端兩次驗(yàn)證(即對jsp中的Form進(jìn)行javascript驗(yàn)證和Action中的excute方法中進(jìn)行驗(yàn)證),不能只采用其中一種方法,防止客戶繞過js直接提交; 在驗(yàn)證登錄提交的form時,必須使用staticJavascript="false",否則就會把javascript寫到頁面里,如: <html:javascript formName="logonForm" dynamicJavascript="true" staticJavascript="false"/> <script language="Javascript1.1" src="staticJavascript.jsp"></script> 驗(yàn)證的formName必須和validation.xml中的Form的名字對應(yīng)起來,否則驗(yàn)證無效 4. ActionForm 是代表html中的Form的,其中的變量需要和Form中的屬性對應(yīng)起來,如:要在jsp中使用<form:text property= "userName"/>,則使用的ActionForm中就必須有userName這個變量 5. 對于Action中的邏輯,如果處理方法在一個以上,需要另外新建一個處理類,負(fù)責(zé)對Action中的邏輯集中處理,命名為xxxDeal,如:LoginDeal; Action通過調(diào)用該處理類的方法,實(shí)現(xiàn)業(yè)務(wù)邏輯處理 6. 對數(shù)據(jù)庫的操作使用DBManager這個類,對其中的一些方法,具體介紹如下: n 查詢結(jié)果對象化的Select操作,使用Select(String sql,String className)方法 StringBuffer sql = new StringBuffer( "select staff_id staffId from ts_m_staff ") .append("where staff_id=‘").append(uid).append("‘"); try { /** * User是一個用戶對象類,其中有staffId這個屬性,以及對應(yīng)的get/set方法,通過 * DBManager的Select方法獲得一個User的ArrayList集合 */ ArrayList rs = DBManager.Select(sql.toString(), User.class.getName()); /** * 如果確定返回的只有一個對象,則可以使用 * */ User user=(User)rs.get(0); } catch (Exception ex) { throw new ServletException(ex.getMessage()); } 取出來的數(shù)據(jù)可以存放在session或page等里,供jsp頁面調(diào)用,方法為session.setAttribute(“user”,user1) … n Insert或Update等操作 使用DBManager里面的executeSql(String sql)方法,如果是批量處理,使用executeBatchSql(String[] sqls)方法,返回成功標(biāo)志為Constants.OPERATE_SUCCESS 失敗標(biāo)志為Constants.OPERATE_FAILED 暫無其它信息返回 n ResultSet對象向Hashtable集合對象的轉(zhuǎn)化,使用select(String sql)方法: 除了可以使用DBManager的Select把查詢結(jié)果轉(zhuǎn)為對象以外,還可以使用以前的直接使用ResultSet對象的方式,不過這里返回的數(shù)據(jù)集對象為Hashtable; Hashtable存放的數(shù)據(jù)結(jié)構(gòu)為: columnName1 ? ArrayList1(該字段的結(jié)果集) columnName2 ? ArrayList2(該字段的結(jié)果集) … 系統(tǒng)中使用該方法的比較多的是用在生成下拉框數(shù)據(jù),從select方法返回的Hashtable取到字段值,并生成LabelValueBean,具體方法如下: /**公用函數(shù) Hashtable 轉(zhuǎn)換成 ArrayList (LabelValueBean)*/ private static ArrayList hashToLVB(Hashtable ht, String id, String name,boolean hasBlank) { if (ht!=null){ ArrayList al = new ArrayList(); ArrayList alId = (ArrayList) ht.get(id.toUpperCase()); ArrayList alName = (ArrayList) ht.get(name.toUpperCase()); int iLen = alId.size(); if (hasBlank) al.add(new LabelValueBean("未知", "-1")); for (int i = 0; i < iLen; i++) { al.add(new LabelValueBean( (String) alName.get(i), (String) alId.get(i))); } return al; } else{ return null; } } n AutoSetForm(String sql, Object frm)方法介紹: a) 該方法可以返回一個查詢數(shù)據(jù)庫后已對其中的屬性賦值的對象,使用方法如下: User user=DBManager. AutoSetForm(sql,new User()); sql為查詢語句 b) 該方法還可以對頁面操作后的Form進(jìn)行賦值,比如在頁面上提交一個對某條記錄進(jìn)行編輯的操作,當(dāng)Action得到該條記錄的Id號并查 詢數(shù)據(jù)庫成功后,需要把各個詳細(xì)信息set到ActionForm的屬性變量中去,這個時候就可以使用該方法,方法如下: form= DBManager. AutoSetForm(sql,form); form為Action的excute方法中傳入的ActionForm 7. 調(diào)用存儲過程 使用DBManager中的execProc(String procName,ArrayList procPrts)方法 procName為存儲過程名,procPrts是該存儲過程的入口參數(shù)集,返回的是ProcOuts的對象,其中有Result和ExceptionInfo兩個屬性,表示返回的處理標(biāo)記和異常信息(如果有的話) 8. 數(shù)據(jù)操作返回信息的處理 在對數(shù)據(jù)操作完成后,需要返回操作是否成功等信息,具體步驟如下: n 使用屬性文件中的“messages.comm”這個key,可以對該key添加具體返回信息 n 程序中使用“ActionMessages”這個對象,java程序如下: ActionMessages ams = new ActionMessages(); … //執(zhí)行結(jié)果 ProcOuts pResult=null; //是否調(diào)用成功 if (pResult.getResult() == -1) { ams.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("message.common", pResult.getExceptionInfo())); } if (!ams.isEmpty()) { saveMessages(request, ams); } Jsp中調(diào)用方法如下: <html:messages id="msg" message="true"> <font color="red"><bean:write name="msg"/></font> </html:messages> |
||||
|
|