<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 78, comments - 34, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    2009-12-21傳智播客——Struts1

    Posted on 2009-12-22 20:24 長城 閱讀(467) 評論(0)  編輯  收藏

             今天是Struts1的第二天,明天是最后一天。看我這么說,多少感覺Struts1有點煩。因為總是使用配置文件,不用怎么寫代碼,一個強大的表單校驗功能就完成了。其實我們一直專注于代碼的重用,減少重復工作所帶來的枯燥與麻煩,從這個角度上想,Struts是相當好的!

             下面我們來看一下今天的重點內容:

    一、復雜驗證

             什么是復雜驗證?相比昨天的簡單驗證(ActionForm)復雜在哪里呢?其一點也不復雜,一說便知。昨天的簡單驗證是對瀏覽器提交的Form表單信息的驗證,比如用戶注冊時輸入的用戶名、密碼、生日、郵箱等信息是否合法。而復雜驗證,就是對業務邏輯的驗證,比如在Action中調用業務邏輯的DAO,驗證用戶的登錄信息是否有效。

             例如,在昨天的練習中添加一個用戶登陸頁面“login.jsp”,添加一個處理用戶登陸的ActionLoginAction”(其實它可以與昨天的用戶注冊Action放到一起,后邊再介紹),再添加一個用戶DAOUserDao”。

    login.jsp 下面為主體部分:

    <body>

        <table align="center">

           <html:form action="${pageContext.request.contextPath }/lgoin.do">

               <tr>

                  <td>用戶名:</td>

                  <td><html:text property="username" /></td>

               </tr>

               <tr>

                  <td>密碼:</td><td><html:password property="password"/></td>

               </tr>

               <tr>

                  <td colspan="2"><html:submit value="登陸"/></td>

               </tr>

           </html:form>

        </table>

    </body>

    發現“<html:xxx…/>”沒有?這是Struts常用的Html標簽,下面會有介紹!

    LoginAction.java,下面為主體部分

    public class LoginAction extends Action {

        @Override

        public ActionForward execute(ActionMapping mapping, ActionForm form,

               HttpServletRequest request, HttpServletResponse response)

               throws Exception {

           // 獲取用戶提交的信息

           String username = request.getParameter("username");

           String password = request.getParameter("passowrd");

           // 調用UserDao查找用戶

           UserDao ud = new UserDao();

           User user = ud.find(username, password);

           // 根據查找結果返回對應信息

           if(user == null){

               // 創建錯誤信息,也可以使用ActionErrors

               ActionMessages errors = new ActionMessages();

               ActionMessage message = new ActionMessage("errors.login.worng");

               errors.add("loginwrong", message);

               // 將信息保存到requestsession中。

               this.saveErrors(request, errors);

               // 跳轉到錯誤頁面

               return mapping.getInputForward();

           }  

           return mapping.findForward("success");

        }

    }

    其中的UserDao就不用列出來了,因為以前做的很多地方都有提到它。

    登陸成功,直接跳轉到昨天添加的“success.jsp”頁面,顯示歡迎信息。如果失敗,則跳轉回登陸頁面,并使用“<html:errors/>”顯示其錯誤信息。在此就不列出了。

    注意一定要在struts-config.xml中配置這個新添加的LoginAction,具體信息如下:

    <action path="/lgoin"

           type="cn.itcast.cc.actions.LoginAction"

           input="/login.jsp">

           <forward name="success" path="/success.jsp"></forward>

    </action>

             昨天落下了一個知識點,信息資源文件。有沒有發現,昨天的代碼和今天的代碼中有類似“ActionMessage("errors.login.worng")”的內容,其中的“"errors.login.worng"”是屬性文件的key。這個屬性文件是通過struts-config.xml配置的:

    <message-resources parameter="MessageResources"></message-resources>

     

             Struts框架根據i18n的文件名稱要求,自動加載配置文件,所有的提示信息都可以在這里設置。

             Ok,上邊就是一個復雜驗證的簡單示例。至于到底有多復雜,視業務邏輯的復雜度而定。

     

    二、處理Struts的中文亂碼問題

             1.Actionexecute方法中有一個“HttpServletRequest”參數,使用這個參數設置編碼格式可不可以?“request.setCharacterEncoding("UTF-8");”。No,如果requestgetParamter方法被調用過,setCharacterEncoding就無效。在什么地方調用了getParamter方法?ActionForm中調用了啊!

             2.編寫一個filter,在這學習過濾器時已經介紹了。是一個好的解決辦法。

             3.我們不是在1中說了,是ActionForm調用了getParameter方法嗎?那就在getParameter之前調用setCharacterEncoding設置編碼。ActionForm之前是什么?是ActionSerlvet,嗯,對的。我們需要使用繼承重寫ActionServlet,并覆蓋ActionServletprocess方法,在process方法里設置編碼。然后修改web.xmlaction名稱的Servlet,使它的類指向我們自定義的ActionServlet

             4.除了通過編寫自己的ActionServlet設置request的編碼,也可以編寫自己的RequestProcessor。什么是RequestProcessorActionServletprocess方法調用了RequestProcessor方法,RequestProcessorActionServlet控制器的核心。所以我們編寫自己的RequestProcessor方法,并覆蓋它的process方法,在process方法中設置request的編碼。完成后,需要在struts-config.xml添加:

    <controller processorClass="cn.itcast.cc.servlet.MyRequestProcessor"/>

             上邊沒什么復雜的,我就不一一實現了!

    三、使用Struts處理表單重復提交的問題和StrutsHTML標簽

             什么是表單重復提交?概括一下:在一個會話中,重復向服務器提交表單數據!這就是表單重復提交。比如,在當前頁面下連續點擊提交按鈕(但頁面一旦被刷新就啟動了一個新會話)。

             在以前學習Session時,也有講過這一問題。這一問題的處理辦法:

    1.        編寫一個JavaScript腳本,當用戶點擊提交按鈕時。使用按鈕變灰(禁用),或設置一個標記,用戶無法點擊,或再次點擊時判斷這個標記值。來防止用戶重復提交表單數據。

    2.        在用戶向服務器請求信息時,比如請求注冊頁面時。在服務器生成一個全球唯一標識符碼,將標識符碼同時保存到Session和頁面的隱藏字段中。當用戶提交注冊信息時,對比Session和隱藏字段中的標識碼,如果相同說明是用戶第一次提交,此時,將Session中的標記碼刪除掉。當用戶再次提交注冊信息時,標識碼已經不相同了(因為sesssion中的已經被刪除了),所以就拒絕這個重復的請求。

    3.        今天我們學習一個新的方便快捷的辦法,處理表單重復提交的問題。此處連同strutsHtml標簽一同介紹了。

    1).我們修改昨天的注冊頁面的Body體內容為:

    <body>

        <table align="center">

           <html:form>

               <tr>

                  <td>用戶名:</td>

                  <td><html:text property="username" /></td>

               </tr>

               <tr>

                  <td>密碼:</td>

                  <td><html:password property="password" /></td>

               </tr>

               <tr>  

                  <td>確認密碼:</td>

                  <td><html:password property="password1" /></td>

               </tr>

               <tr>

                  <td>生日:</td>

                  <td><html:text property="birthday" "/></td>

               </tr>

               <tr>

                  <td><html:submit value="注冊"/></td>

                  <td><html:reset value="重填"/></td>

               </tr>

           </html:form>

        </table>

    </body>

             使用strutsHTML標簽有什么好處?

    1.        驗證表單錯誤,表單回顯。

    2.        將表單與ActionForm進行校驗,如果出現錯誤就拋異常。昨天沒有使用strutsHTML標簽時,是不會拋異常的。

    注意:如果表單中存在“<html:checkbox/>”選項,它是不會被回顯的,應當使用:<html:multibox property="interesting" value="reading"></html:multibox>

             2).在加載表單之前調用“TokenProcessor.saveToken()”方法,它會自動向表單和Session中添加全球唯一標識符(自動創建表單中的隱藏字段)。比如,我們可以在跳轉到JSP頁面的Action中添加“TokenProcessor.saveToken()”方法,也可以在JSP頁面的表單之前添加““TokenProcessor.saveToken()”方法”。這里我們在JSP頁面的表單之前添加:

    <%

        org.apache.struts.util.TokenProcessor.getInstance().saveToken(request);

        %>

             3).啟動服務器,訪問注冊頁面。查看注冊頁面的源代碼,發現自動生成了以下部分:

    <form name="regForm" method="post" action="/091220StrutsLogin/reg.do;jsessionid=13ADEF2ADC0126D626FBE49EC98F5EFF">

        <div>

           <input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="cb279a07b286c393c7c1081a49e44313">

        </div>

    其中 form 中的namemethodjsessionid<div>中的內容是自動添加的。

    Name是表單ActionForm的名字,Sturts使用它與ActionForm進行校驗。

    Method是表單的提交方式。

    Jsessionid當第一次請求注冊頁面時,或cookie被禁用時。Sturts框架會自動進行URL重寫。

    <div>中的內容是防止表單重復提交。

             4).在處理注冊信息的Action中調用“TokenProcessor.isTokenValid(request)”方法用于判斷表單是否重復提交,返回真為第一次提交,返回假為重復提交。然后調用“TokenProcessor.getInstance().resetToken(request);”方法清除seission的防止表單重復提交的信息,從此以后isTokenValid方法返回假。

                      

    常用的Struts HTML標簽(老佟的):

    標簽

    用途/注解

    html

    產生一個<html>標簽。也包括來自于用戶會話中的 language 屬性

    form

    定義一個表單。Action focus 屬性是最有用的屬性

    checkbox

    產生一個檢查框字段

    file

    產生一個文件選擇輸入字段

    hidden

    產生一個隱藏字段

    option

    產生一個選擇項

    options

    產生一個選擇項列表

    password

    產生一個口令輸入字段

    radio

    產生一個單選輸入字段

    select

    產生一個選擇元素

    text

    產生一個文本輸入字段

    textarea

    產生一個 html 文本區域元素

    image

    產生一個圖像輸入字段

    button

    產生一個按鈕輸入字段

    cancel

    產生一個取消按鈕

    submit

    產生一個提交按鈕

    reset

    產生一個重新設定按鈕

    errors

    顯示錯誤消息

    img

    產生一個 html img 標簽

     

    四、使用Strutsvalidator插件進行簡單的表單驗證

             之前我們使用的是ActionForm進行表單的簡單驗證,在那里我們需要手動的進行各個字段的合法性驗證,這是一個重復的工作,而且十分無聊。Validator插件,就是用于解決這個問題的。

    1.struts中引入插件,需要向struts-config.xml文件添加:

    <plug-in className="org.apache.struts.validator.ValidatorPlugIn">

            <set-property property="pathnames"

                    value="/org/apache/struts/validator/validator-rules.xml,

                                 /WEB-INF/validation.xml" />

        </plug-in>

       

    其中pathnames屬性的兩個值:

    1)./org/apache/struts/validator/validator-rules.xml”中定義了Validator提供的字段約束。validator-rules.xml文件在struts-core-1.3.8.jarorg.apache. struts.validator包中。

    2)./WEB-INF/validation.xml”是Validator的配置文件。

    2.如果你知道這個文件內容應該是什么樣子。可以到struts包的apps目錄下,解壓縮struts-cookbook-1.3.8.war,在它的WEB-INF目錄下就有一個validation.xml文件。我們向“WEB-INF”目錄下添加“validation.xml”文件,并添加內容:

    <form-validation>

        <formset>

           <form name="validatorForm">

    <!—- 用戶名 -->

               <field property="username" depends="minlength">

                    <arg key="validator.min" position="0"/>

                  <arg key="${var:minlength}" resource="false" position="1"/>             

                  <var>

                      <var-name>minlength</var-name>

                      <var-value>6</var-value>

                  </var>

               </field>

    <!—- 密碼 -->

               <field property="password" depends="required,minlength">

                  <arg key="validator.password" position="0" />

                  <arg key="${var:minlength}" resource="false" position="1" name="minlength"/>

                  <var>

                      <var-name>minlength</var-name>

                      <var-value>5</var-value>

                  </var>

               </field>

              

               <field property="password2" depends="validwhen">

                  <msg name="validwhen" key="validator.validwhen.password2"/>

                  <var>

                      <var-name>test</var-name>

                      <var-value>(*this*==password)</var-value>

                  </var>

               </field>

    <!—- 生日 -->

               <field property="birthday" depends="date">

                  <arg key="validator. birthday" />

                 

                  <var>

                      <var-name>datePattern</var-name>

                      <var-value>yyyy-MM-dd</var-value>

                  </var>

               </field>

           </form>

        </formset>

    </form-validation>

             1).<form name="validatorForm">”指定ActionForm,這個ActionForm不需要編寫自己的validate方法。

             2).一個<filed></filed>設置一個表單中的字段:

    .property="username"”指向注冊頁面“<html:text property="username" />”。

    .<arg key="validator.min" position="0"/>key指向配置文件MessageResources.properties中自定義的keyPosition用于替換第1個位置“{0}”,因為在milength約束中有“msg="errors.minlength"”設置,errors.minlengthMessageResources.properties中自定義。

    .<arg key="${var:minlength}" resource="false" position="1"/>”,key指向下邊的<var>resource="false"為不讀取MessageResources.properties文件,替換第2個位置“{1}”。

    . <var>”定義一個自己的變量,用于設置字符串的最小長度。

                       .密碼部分就不做詳解了,但其中“<msg name="validwhen" key="validator.validwhen.password2"/>”用于替換“validwhen”的默認錯誤信息。

                       .生日部分也不做詳解了。

     

    五、DispatchAction,同一類請求綜合處理

             同學提問了一個好問題,以前在做練習時,每個請求都單獨寫一個Servlet,現在的Action我們也要這么寫嗎?當然不是!如果開發一個大工程,有上千個請求,難道要寫上千個Action嗎?DispatchAction為我們解決了這個問題。

             例,處理用戶注冊、登陸、更新、刪除的這一類請求,我們可以編寫一個DispatchAction

    import javax.servlet.http.*;

    import org.apache.struts.action.*;

    import org.apache.struts.actions.DispatchAction;

     

    public class TestDispatchAction extends DispatchAction {

        // add處理

        public ActionForward add(ActionMapping mapping, ActionForm form,

               HttpServletRequest request, HttpServletResponse response)

               throws Exception {

           System.out.println("TestDispatchAction.add");

           return mapping.findForward("success");

        }

        // find處理

        public ActionForward find(ActionMapping mapping, ActionForm form,

               HttpServletRequest request, HttpServletResponse response)

               throws Exception {

           System.out.println("TestDispatchAction.find");

           return mapping.findForward("success");

        }

    }

             我們需要在struts-config.xml添加如下配置:

    <?xml version="1.0" encoding="UTF-8" ?>

    <!DOCTYPE struts-config PUBLIC

              "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"

              "http://struts.apache.org/dtds/struts-config_1_3.dtd">

    <struts-config>

        <action-mappings>

           <action path="/action"

               type="cn.itcast.cc.actions.TestDispatchAction"

               parameter="method">

               <forward name="success" path="/WEB-INF/pages/success.jsp" />

           </action>

        </action-mappings>

    </struts-config>

             其中的“parameter="method"”,這里的“method”必須與下面的JSP頁面中的請求參數名稱相同。TestDispatchAction中的方法名稱與參數值相同,參數值指向哪個方法,DispacthAction就調用哪個方法。

             JSP頁面:

    <%@ page language="java" contentType="text/html; charset=UTF-8"

        pageEncoding="UTF-8"%>

    <%@ taglib prefix="html" uri="http://struts.apache.org/tags-html"%>

     

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

    <html>

    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    <title>Insert title here</title>

    </head>

    <body>

    <html:link action="/action.do?method=add">add</html:link>

    <html:link action="/action.do?method=find">find</html:link>

    </body>

    </html>

             其中的http://struts.apache.org/tags-html在是菜單:widnow->perferences->XML->XML Catalog添加的,它是指向“struts-1.3.8\docs\dtds\struts-config_1_3.dtd”的URI

             嗯,今天結束!看似內容并不多,但要熟練掌握還要多加練習。

             加油!


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 亚洲啪啪AV无码片| 伊人久久大香线蕉亚洲五月天| 亚洲国产欧美国产综合一区| 免费中文字幕一级毛片| 91在线免费观看| 亚洲第一网站免费视频| 免费高清小黄站在线观看 | 成在线人永久免费视频播放| 中文字幕无码免费久久| 亚洲另类无码专区丝袜| 久久91亚洲精品中文字幕| 曰皮全部过程视频免费国产30分钟 | 久久久久久a亚洲欧洲AV| 亚洲午夜久久久精品影院| 国产免费小视频在线观看| h在线观看视频免费网站| 美女免费精品高清毛片在线视| 亚洲电影一区二区三区| 亚洲色偷偷偷网站色偷一区| 亚洲欧洲日产国码高潮αv| 免费精品国产自产拍在线观看图片 | 亚洲视频在线精品| 国产v片免费播放| 亚洲中文字幕无码专区| 亚洲精品色午夜无码专区日韩| 永久久久免费浮力影院| 大胆亚洲人体视频| 女人18毛片a级毛片免费视频| 亚洲网站免费观看| 久久久精品免费国产四虎| 一级毛片免费播放试看60分钟| 中国china体内裑精亚洲日本| 亚洲AV无码久久精品成人| 亚洲日韩中文在线精品第一| 亚洲乱码日产一区三区| 亚洲美女中文字幕| 国产青草亚洲香蕉精品久久 | 国产亚洲av片在线观看16女人| 久久久久久亚洲精品成人| 亚洲av永久无码精品漫画| 亚洲国产精品综合久久2007|