2006年12月27日

          ?public ActionErrors validate(ActionMapping actionMapping,
          ???????????????????????????????? HttpServletRequest httpServletRequest) {
          ??????? String style =
          ??????????????? "^[a-zA-Z][a-zA-Z0-9._-]*@([a-zA-Z0-9-_]+\\.)+(com|gov|net|com\\.cn|edu\\.cn)$";
          ??????? Pattern ptt = Pattern.compile(style);
          ??????? Matcher mch=ptt.matcher(email);
          ??????? ActionErrors errors = new ActionErrors();
          ??????? if ((name == null || name.equals(""))) {
          ??????????? ActionError error = new ActionError("error.name");
          ??????????? errors.add("name", error);
          ??????? } else
          ??????? if (!mch.matches()) {
          ??????????? ActionError error = new ActionError("error.email");
          ??????????? errors.add("email", error);
          ??????? }
          ??????? return errors;
          ??? }

          posted @ 2006-12-28 11:58 鷺 閱讀(1305) | 評論 (0)編輯 收藏

          在Struts中,擔任 MVC / Model 2 中Controller角色的是ActionServlet,所有的請求都必須先通過它,然而在Struts 1.1後,有關於請求的處理大部份已交由RequestProcessor,當ActionServlet收到GET或POST的請求,其doGet() 或doPost()會呼叫process()方法來處理請求:
          protected void process(HttpServletRequest request,
          ??????????????????????? HttpServletResponse response)
          ?????????????????? throws IOException, ServletException {
          ??? RequestUtils.selectApplication(request,
          ?????????????????????????????????? getServletContext());
          ??? getApplicationConfig(
          ???????? request).getProcessor().process(request, response);
          }
          ?
          RequestUtils是個工具類,ActionServlet呼叫其selectApplication()方法,藉由 request.getServletPath()來取得請求路徑以選擇應用程式模塊來處理請求,之後從ApplicationConfig物件取得 RequestProcessor物件,將使用者的請求委托它來進行處理。

          通常是將ActionServlet當作黑盒子,您只要使用它,然而您也可以繼承ActionServlet來定義自己的控制器,但由於在Struts 1.1中大部份的請求已經委托RequestProcessor來處理,繼承ActionServlet來定義自己的控制器請求處理意義已經不大,通常的 目的是重新定義ActionServlet的init()方法,增加自己的初始化動作:
          public class CustomActionServlet extends ActionServlet {
          ??? public void init() throws ServletException {
          ??????? super.init();

          ??????? // 增加自己的初始化動作
          ??????? ....
          ??? }
          }
          ?
          預設的RequestProcessor物件是org.apache.struts.action.RequestProcessor,您可以藉由觀看 process()方法的原始碼來了解它作了哪些事情:
          public void process(HttpServletRequest request,
          ???????????????????? HttpServletResponse response)
          ????????????????? throws IOException, ServletException {
          ??? // 處理 contentType 為 multipart/form-data 的 POST 請求
          ??? request = processMultipart(request);

          ??? // 取得 URI 路徑
          ??? String path = processPath(request, response);
          ??? if(path == null)
          ??????? return;
          ??? .....

          ??? // 確定客戶端的位置
          ??? // 是否要將一個Locale物件儲存在 session 中
          ??? // 配合 <controller> 的 locale 屬性使用
          ??? processLocale(request, response);

          ??? // 確定contentType,預設是 text/html
          ??? processContent(request, response);

          ??? // 判斷<controller>屬性nocache是否被確定
          ??? // 若是,在 response 中加入防止快取的header
          ??? processNoCache(request, response);

          ??? // 前置處理,預設返回 true
          ??? //子類可以重新定義它以決定要不要繼續處理
          ??? if(!processPreProcess(request, response)) {
          ??????? return;
          ??? }

          ??? // 從URI路徑確定ActionMapping
          ??? ActionMapping mapping =
          ?????????????????? processMapping(request, response, path);
          ??? if(mapping == null) {
          ??????? return;
          ??? }

          ??? ....

          ??? // 處理ActionForm
          ??? // 如果沒有就新增一個,之後一直使用它
          ??? ActionForm form =
          ??????????? processActionForm(request, response, mapping);
          ???
          ??? // 將表單的欄位值填入ActionForm
          ??? processPopulate(request, response, form, mapping);

          ??? // 判斷是否執行ActionForm的validate()方法
          ??? if(!processValidate(request, response, form, mapping)) {
          ??????? return;
          ??? }

          ??? // 判斷 標簽的 forward 或 include 標簽
          // 是不是被設定,這兩個標簽在設定一個路徑
          // 其與 type 屬性是互斥的,當設定其中一個屬性時
          // 調用 RequestDispatcher 的 forward() 或 include()
          // 其作用與設定ForwardAction或IncludeAction相同
          // 直接繞送而不再使用Action物件進行接下來的處理

          ??? if(!processForward(request, response, mapping)) {
          ??????? return;
          ??? }
          ??? if(processInclude(request, response, mapping)) {
          ??????? return;
          ??? }

          ??? // 處理Action,如果沒有就生成一個,之後一直使用它
          ??? Action action =
          ??????????? processActionCreate(request, response, mapping);
          ??? if(action == null) {
          ??????? return;
          ??? }

          ??? // 呼叫Action的execute()或perform()方法
          // 并返回ActionForward

          ??? ActionForward forward =
          ??????????????????? processActionPerform(request,
          ???????????????????????????????????????? response,
          ???????????????????????????????????????? action,
          ???????????????????????????????????????? for, mapping);

          ??? // 處理ActionForward
          ??? processActionForward(request, response, forward);
          }
          ?

          您可以繼承RequestProcessor,并改寫其中的processXXXXX()方法來自定義請求的處理方式,如果您要使用自己的 RequestProcessor,要在struts-config.xml中使用<controller>標簽來定義,例如:
          • struts-config.xml
          ...
          <controller
          contentType="text/html;charset=Big5"
          locale="true"
          nocache="true"
          processorClass="caterpillar.CustomRequestProcessor"/>
          ...

          在Struts 1.1後,新增了<controller>標簽,它可以用於指定ActionServlet的一些參數,在Struts 1.1之前,這些參數是在<init-params>中加以指定,使用<controller>標簽,應用程式中不同的模組也可 以指定各自的參數給ActionServlet。

          posted @ 2006-12-28 10:24 鷺 閱讀(832) | 評論 (0)編輯 收藏

          html:link有很多參數選項,如關鍵有:
          action --指定點擊鏈接后,進入的*.do動作action的值不需要跟后綴,struts自動補上.do
          page? -- 跟action一樣的功能,不過這個不會自動補.do,也就是說可以鏈接其他類型的動作,如html,jsp,php等

          paramId--指定參數的key名稱,如要輸出paramName -- 能識別作用域(任意)內的Object的名稱。
          paramProperty--paramName的輸出屬性,paramId,paramName ,paramProperty可以組成單一參數傳遞的link,如<html:link? action="/PRC301E1"? paramId="prc_no" paramName="element" paramProperty="fjPrcNo">,當element.getfjPrcNo()的值為prc1時,則輸出為
          http://xxoo.com/PRC301E1.do?prc_no=prc1

          name--為HashMap屬性的對象,用此屬性,可以進行多參數輸出。例:

          CODE:
          [Copy to clipboard]
          ???? <%
          ??????? HashMap map=new HashMap();
          ?????? map.put("check","22");
          ?????? map.put("name","abc");
          ?????? pageContext.setAttribute("map",map); //因為所有tag的取值只會搜索作用域(page/request/session/application),而不會識別當前的實例,所以只有存入。
          ????? %>
          ????? <html:link action="/PRC301E1"? name="map">
          ??????? 多參數輸出
          ????? </html:link>

          -----------------------------------------------------------------------------------------

          在struts標簽<html:link>的page屬性指定的URI后面傳遞參數可以有幾種方式:

          1.若明確參數名和參數值則直接在URI后輸出,
          如:<html:link page="/test.do?action=add">add</html:link>

          2.對于參數值不確定的,paramName和paramProperty來輸出,用paramId屬性指定參數名。
          對于paramName指定的對象應該存在于page、request、session、application其中之一。一般來說,是從Action類傳過來的,作為request的屬性之一(requst.setAttribute("name",object))。
          如果paramName指定的對象是action的ActionForm,則無需使用request.setAttribute方法。
          例:<html:link page="/test.do" paramId="userid" paramName="uid">uname</html:link>
          若參數值是一個bean對象的屬性值(比如ActionForm,或者集合中存放的對象)則:
          <html:link page="/test.do" paramId="userid" paramName="user" paramProperty="uid">uname</html:link>

          3.若兩個參數,一個確定一個不確定,則是以上兩種方法的結合,即:
          <html:link page="/test.do?action=modify" paramId="userid" paramName="uid">modify</html:link>

          4.對于多個參數的問題,可以使用一個HashMap集合對象來存放所有的參數名及對應的參數值的方式,paramName屬性值指定為該HashMap集合對象即可。
          舉例:
          <%
          //代碼理想的位置應該是在action中
          //可以在jsp頁面測試
          ? java.util.HashMap pms = new java.util.HashMap();
          ? pms.put("code", "001002");
          ? pms.put("name", "tester");
          ? pms.put("alias", new String[]{"matin","jack"});
          ? request.setAttribute("params", pms);
          %>
          <html:link action="/test.do" name="params" >test</html:link>
          編譯后的結果:<a href="/test.do?code=001002&name=tester&alias=matin&alias=jack">test</a>
          這種方式雖然可以解決傳多參數的問題,但是實現起來也比較麻煩,特別是對記錄集中的數據逐條列出的時候

          5.針對有的網友在<html:link>標簽中嵌入使用jsp腳本(scriptlet)的問題,
          例如:
          <html:link page="/test.do?code=<%=varible%>">add</html:link>,這種寫法是錯誤的,是無法編譯的。
          有的網友認為在struts標簽內是不允許使用jsp腳本的,這種說法也不準確。如果前面的寫法改成:
          <html:link page="<%="/test.do?code="+varible%>">add</html:link>,就可以被執行,但是要注意URL相對路徑的問題。

          雖然在struts標簽中嵌入jsp腳本不是真正意義上的struts應用,但是有時在委曲求全的情況下也只能如此了,除非使用自定義標簽。比如在form表單中可能需要根據具體數據讓某個字段是只讀的,就可以用嵌入jsp腳本來實現:
          <%
          boolean rdonly=false;
          if(2==2) rdonly=true;
          %>
          <html:text property="userid" readonly="<%=rdonly%>" />

          6.另外一種比較變態的方法,既不是真正意義上的struts,也不符合xml規范。那就是在<a>標簽中用<bean:write>標簽輸出參數值。
          如:<a href="test.do?uid=<bean:write name="user" property="userid"/>&name=<bean:write name="user" property="username"/>">test</a>

          posted @ 2006-12-27 14:35 鷺 閱讀(356) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 崇明县| 通渭县| 东宁县| 泾川县| 收藏| 儋州市| 仙桃市| 蒙自县| 富川| 吴川市| 姜堰市| 巢湖市| 漯河市| 深水埗区| 五大连池市| 满城县| 汽车| 平谷区| 迁西县| 渭源县| 绵阳市| 吴川市| 临清市| 额济纳旗| 巍山| 汉中市| 奉新县| 育儿| 新建县| 托里县| 徐汇区| 麟游县| 闵行区| 遂溪县| 仲巴县| 克拉玛依市| 嘉兴市| 金山区| 广饶县| 义乌市| 北安市|