<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 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

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

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

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

             下面我們來看一下今天的重點內(nèi)容:

    一、復(fù)雜驗證

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

             例如,在昨天的練習(xí)中添加一個用戶登陸頁面“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>

    發(fā)現(xiàn)“<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");

           // 調(diào)用UserDao查找用戶

           UserDao ud = new UserDao();

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

           // 根據(jù)查找結(jié)果返回對應(yīng)信息

           if(user == null){

               // 創(chuàng)建錯誤信息,也可以使用ActionErrors

               ActionMessages errors = new ActionMessages();

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

               errors.add("loginwrong", message);

               // 將信息保存到requestsession中。

               this.saveErrors(request, errors);

               // 跳轉(zhuǎn)到錯誤頁面

               return mapping.getInputForward();

           }  

           return mapping.findForward("success");

        }

    }

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

    登陸成功,直接跳轉(zhuǎn)到昨天添加的“success.jsp”頁面,顯示歡迎信息。如果失敗,則跳轉(zhuǎn)回登陸頁面,并使用“<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>

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

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

     

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

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

     

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

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

             2.編寫一個filter,在這學(xué)習(xí)過濾器時已經(jīng)介紹了。是一個好的解決辦法。

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

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

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

             上邊沒什么復(fù)雜的,我就不一一實現(xiàn)了!

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

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

             在以前學(xué)習(xí)Session時,也有講過這一問題。這一問題的處理辦法:

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

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

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

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

    <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進行校驗,如果出現(xiàn)錯誤就拋異常。昨天沒有使用strutsHTML標簽時,是不會拋異常的。

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

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

    <%

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

        %>

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

    <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>中的內(nèi)容是自動添加的。

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

    Method是表單的提交方式。

    Jsessionid當(dāng)?shù)谝淮握埱笞皂撁鏁r,或cookie被禁用時。Sturts框架會自動進行URL重寫。

    <div>中的內(nèi)容是防止表單重復(fù)提交。

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

                      

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

    標簽

    用途/注解

    html

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

    form

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

    checkbox

    產(chǎn)生一個檢查框字段

    file

    產(chǎn)生一個文件選擇輸入字段

    hidden

    產(chǎn)生一個隱藏字段

    option

    產(chǎn)生一個選擇項

    options

    產(chǎn)生一個選擇項列表

    password

    產(chǎn)生一個口令輸入字段

    radio

    產(chǎn)生一個單選輸入字段

    select

    產(chǎn)生一個選擇元素

    text

    產(chǎn)生一個文本輸入字段

    textarea

    產(chǎn)生一個 html 文本區(qū)域元素

    image

    產(chǎn)生一個圖像輸入字段

    button

    產(chǎn)生一個按鈕輸入字段

    cancel

    產(chǎn)生一個取消按鈕

    submit

    產(chǎn)生一個提交按鈕

    reset

    產(chǎn)生一個重新設(shè)定按鈕

    errors

    顯示錯誤消息

    img

    產(chǎn)生一個 html img 標簽

     

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

             之前我們使用的是ActionForm進行表單的簡單驗證,在那里我們需要手動的進行各個字段的合法性驗證,這是一個重復(fù)的工作,而且十分無聊。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.如果你知道這個文件內(nèi)容應(yīng)該是什么樣子。可以到struts包的apps目錄下,解壓縮struts-cookbook-1.3.8.war,在它的WEB-INF目錄下就有一個validation.xml文件。我們向“WEB-INF”目錄下添加“validation.xml”文件,并添加內(nèi)容:

    <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>設(shè)置一個表單中的字段:

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

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

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

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

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

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

     

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

             同學(xué)提問了一個好問題,以前在做練習(xí)時,每個請求都單獨寫一個Servlet,現(xiàn)在的Action我們也要這么寫嗎?當(dāng)然不是!如果開發(fā)一個大工程,有上千個請求,難道要寫上千個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頁面中的請求參數(shù)名稱相同。TestDispatchAction中的方法名稱與參數(shù)值相同,參數(shù)值指向哪個方法,DispacthAction就調(diào)用哪個方法。

             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

             嗯,今天結(jié)束!看似內(nèi)容并不多,但要熟練掌握還要多加練習(xí)。

             加油!


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲一区二区影院| 一级特级aaaa毛片免费观看| 青青操免费在线观看| 欧洲精品成人免费视频在线观看 | 久视频精品免费观看99| 亚洲国产综合无码一区二区二三区| 久久99热精品免费观看动漫| 国产成人一区二区三区视频免费| 久久A级毛片免费观看| 国产成人精品亚洲精品| 亚洲日产乱码一二三区别| 免费无码专区毛片高潮喷水 | 亚洲中文字幕无码永久在线| 亚洲一区二区三区日本久久九| 成人a毛片免费视频观看| 99在线观看免费视频| 白白国产永久免费视频| 在线观看亚洲成人| 婷婷亚洲综合五月天小说在线 | 亚洲国产成人久久精品app| 国内永久免费crm系统z在线 | 好看的亚洲黄色经典| 2020天堂在线亚洲精品专区| 久9久9精品免费观看| 日韩亚洲变态另类中文| 欧亚一级毛片免费看| 国产免费卡一卡三卡乱码| 亚洲AV无码成人专区片在线观看 | 国产成人亚洲精品电影| 西西人体免费视频| 一本色道久久88亚洲综合| 亚洲短视频在线观看| 未满十八私人高清免费影院| 国产色爽免费视频| 亚洲乱人伦中文字幕无码| 18禁超污无遮挡无码免费网站国产| 亚洲毛片免费观看| 中文字幕免费视频| 中文字幕亚洲第一在线| 9420免费高清在线视频| 亚洲高清日韩精品第一区|