欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
struts源代碼閱讀(struts 的執行)
第二篇  struts的執行(struts-1.1版)

本篇詳細介紹struts在初始化之后是如何處理一個(gè)請求,并返回數據的。這里最核心的類(lèi)是
requestprocessor以及requestutils。requestprocessor類(lèi)通過(guò)requestdispatcher實(shí)現頁(yè)面的跳轉,
而requestprocessor負責處理request中傳來(lái)的請求信息,存放到formbeanconfig中,以及對要跳轉的
url進(jìn)行處理。

struts 在初始化完成之后,會(huì )根據請求調用doget(...)或者dopost(...)方法,這兩個(gè)方法直接
調用process(request, response)方法。process(...)方法首先判斷當前的request屬于
哪一個(gè)moduleconfig,然后生成與這個(gè)moduleconifg相對應的requestprocessor,最后調用這個(gè)
requestprocessor的process(...)方法,執行request的請求。

一、requestutils.selectmodule(string prefix, httpservletrequest,servletcontext)方法:
    這個(gè)方法,根據prefix,從servletcontext中選擇相應的moduleconfig,然后把這個(gè)moduleconfig
    保存到request中。servletcontext對應的key值為globals.module_key + prefix,保存到request
    中使用的key值為globals.module_key。如果在servletcontext中不存在這樣的一個(gè)moduleconfig,
    那么調用request.removeattribute(globals.module_key)方法。然后以同樣的方法查找、保存
    messageresources對象。當prefix為空時(shí),會(huì )調用下面的方法選擇moduleconfig。

二、requestutils.selectmodule(httpservletrequest, servletcontext)
    這個(gè)方發(fā)首先使用getmodulename(httpservletrequest, servletcontext)獲取相應的path,然后
    通過(guò)調用getmodulename(string matchpath, servletcontext)獲取相應的prefix。以這prefix為
    參數調用(一)中的selectmodule(...)選擇moduleconfig。
    獲取path的過(guò)程為:首先從request中查找名稱(chēng)為
    include_servlet_path(javax.servlet.include.servlet_path)的屬性,如果為空,就調用
    request.getservletpath()方法獲取servletpath。

    獲取prefix的過(guò)程為:它首先調用getmoduleprefixes(servletcontext),獲取所有已存在的
    module前綴。 然后通過(guò)分析上面獲取的path來(lái)判斷當前的url屬于哪一個(gè)module,方法是截取
    path中最后一個(gè)"/"字符前面的字符串,然后與有上面方法中獲取的prefixes[]逐個(gè)對比,如果
    prefixes[]中存在這樣的一個(gè)值,則返回這個(gè)截取的字符串,否則繼續截取path最后面的"/"前面
    的字符串,然后對比。如果始終找不到,則返回""。

    getmoduleprefixes(servletcontext)的執行過(guò)程是:首先通過(guò)
    context.getattribute(prefixes_key)查找是否存在這樣的一個(gè)保存所有的prefix的string array,
    如果存在,就說(shuō)明已經(jīng)解析過(guò)一次了,就直接返回這個(gè)string array,否則遍歷servletcontext中
    所有的attribute name,查找以module_key(org.apache.struts.action.module)開(kāi)頭的
    atrribute name,然后截取這個(gè)atrribute name中module_key后面的字符串,作為一個(gè)prefix. 最
    后把通過(guò)這個(gè)這個(gè)方式獲取的所有的prefix作為一個(gè)arraylist存儲到servletcontext中,屬性key
    值為prefixes_key(org.apache.struts.util.prefixes),這樣下次再次查找的時(shí)候就可以直接從這
    個(gè)attribute中獲取了。

三、getmoduleconfig(httpservletrequest)
    這個(gè)方法就是獲取上面的selectmodule(...)方法所得到的moduleconfig。如果找不到這樣的
    moduleconfig,那么就把servletcontext中缺省的moduleconfig返回(調用
    getservletcontext().getattribute(globals.module_key))

四、getrequestprocessor(moduleconfig config)
    這個(gè)方法從根據moduleconfig的prefix作為key,從servletcontext中獲取requestprocessor。這
    個(gè)key值為globals.request_processor_key + config.getprefix()。

    如果servletcontext中不存在這樣的一個(gè)requestprocessor,那么就生成一個(gè)新的
    requestprocessor的實(shí)例,完成初始化(保存actionservlet以及moduleconfig到這個(gè)新的實(shí)例中)后
    將其保存到servletcontext中。

五、requestprocessor.process(httpservletrequest, httpservletresponse)
    這是真正執行httpservletrequst請求的方法。

    這個(gè)方法首先判斷但前的httpservletrequest是否是multipart類(lèi)型的request,也就是說(shuō)當前
    的request是否有字段是"file"類(lèi)型。這樣做的原因是這種類(lèi)型的request中g(shù)etparameter()等
    相類(lèi)似的方法都是無(wú)法執行的,所以要區分對待。如果是multipart類(lèi)型的,那么把這個(gè)request包
    裝成multipartrequestwrapper類(lèi)。

    multipartrequestwrapper 與 httpservletrequest不同的就是重新實(shí)現了
    setparameter(string name, string value),getparameter(string name),getparameternames()
    以及getparametervalues(string name)方法。
    這些方法的思想是所有的變量名、值對都保存到一個(gè)hashmap里:key為變量名,value為變量值,但
    是注意value都是string[]格式的。當有一個(gè)新的值加入的時(shí)候,通過(guò)setparameter(...)
    方法,把值加到數組的最后。在setparameter(...)中有一個(gè)比較少見(jiàn)的保存值的方法,記錄如下:
    public void setparameter(string name, string value) {
        string[] mvalue = (string[]) parameters.get(name);
        if (mvalue == null) {
            mvalue = new string[0];
        }
        string[] newvalue = new string[mvalue.length + 1];
        system.arraycopy(mvalue, 0, newvalue, 0, mvalue.length);
        newvalue[mvalue.length] = value;
        
        parameters.put(name, newvalue);
    }

    然后是調用processpath(httpservletrequest, httpservletresponse)獲取地址,以這個(gè)地址作為
    從moduleconfig獲取actionmapping的key。這里首先查詢(xún)
    request.getattribute(include_path_info)中是否有這樣的一個(gè)值,如果為空就調用
    request.getpathinfo()方法獲取path。如果這樣還是獲取不了,就從
    request.getattribute(include_servlet_path)方法中獲取path,找不到就使用
    request.getservletpath()得到的path進(jìn)行分析。分析過(guò)程如下:

    然后如果這個(gè)path不是屬于當前的moduleconfig的話(huà),直接返回null。截取prefix后面的字符串,
    如果這個(gè)字符串以.xx結尾,那么就截取"."前面的字符,比如
    http://localhost:8080/servlet/where/go.do。where為module的名稱(chēng)(prefix),那么我們獲取的
    path值為/go。

    然后是通過(guò)processlocale(httpservletrequest ,httpservletresponse)為當前用戶(hù)設定一個(gè)local
    對象,它查找的順序是:moduleconfig.getcontrollerconfig().getlocale(),
    session.getattribute(globals.locale_key),request.getlocale()。你可以在config xml文件
    中通過(guò)<controller><set-property..../></controller>執行相關(guān)的定義。

    調用processcontent(httpservletrequest, httpservletresponse)為response設定contenttype。
    這個(gè)contenttype是從moduleconfig.getcontrollerconfig().getcontenttype()獲取的。你可以
    在config xml文件中通過(guò)<controller><set-property..../></controller>執行相關(guān)的定義。

    通過(guò)processnocache(httpservletrequest, httpservletresponse)方法設置response的緩存。
    你可以在config xml文件中通過(guò)<controller><set-property..../></controller>執行相關(guān)的定義。

    processpreprocess(httpservletrequest, httpservletresponse)預處理request,這個(gè)方法是預
    留的,用戶(hù)可以根據自己的需要加一些預處理的程序。

    通過(guò)processmapping(httpservletrequest, httpservletresponse, string path)以
    processpath(...)的返回值為key從moduleconfig中查找actionmapping 對象。如果找到了,那么保
    存這個(gè)mapping到request中,key值為globals.mapping_key。如果不存在,那么遍歷moduleconfig
    中所有的actionmapping,查找哪一個(gè)是缺省的actionmapping。然后把它保存到request中,key值
    為globals.mapping_key。

    通過(guò)processroles(httpservletrequest,httpservletresponse,actionmapping)檢查當前用戶(hù)是
    否有權限執行這個(gè)請求。如果request.isuserinrole(roles[i])返回true,則代表有。

    通過(guò)processactionform(httpservletrequest, httpservletresponse, actionmapping)生成一個(gè)
    actionform,然后根據actionmapping所屬的scope,保存到request或者session中。key值為這個(gè)
    actionmapping中的attribute屬性。actionform是通過(guò)requestutils.createactionform(...)方法
    獲取的,在下一篇將會(huì )對這個(gè)方法進(jìn)行詳細的說(shuō)明。這里只說(shuō)明actionform與formbeanconfig以及
    formpropertyconfig之間的區別。每個(gè)formpropertyconfig代表form表單的一個(gè)字段,表單中的所
    有formpropertyconfig以一個(gè)hashmap保存到formbeanconfig中。而formbeanconfig是在
    actionservet初始化的時(shí)候生成的:
    <form-beans>
      <form-bean name="一個(gè)名稱(chēng),作為action選擇的key" type="實(shí)際對應的actionform類(lèi)"/>
    <form-beans>
    名稱(chēng)用來(lái)在moudleconfig中的formbeans hashmap中查找相應的formbeanconfig,而formbeanconfig
    中有一個(gè)type,它保存了上面xml文件中定義的值,用來(lái)生成actionform。
    
    通過(guò)processpopulate(httpservletrequest, httpservletresponse, actionform,
    actionmapping)方法初始化actionform 以及 formbean,這個(gè)方法首先會(huì )設定這個(gè)actionform所屬
    于的actionservlet,然后對這個(gè)actionform進(jìn)行初始化。判斷當前的reqest是否multipart類(lèi)型,
    如果是就把相應的multipartclass類(lèi)全名保存到request中,key值為globals.multipart_key。調
    用requestutils.populate(...)對request中的參數進(jìn)行處理,并保存到相應的formbean中。在下
    一篇將會(huì )對這個(gè)方法進(jìn)行詳細的說(shuō)明。最后根據request的parameter判斷當前的請求是否是被取
    消,然后把相關(guān)信息保存到request中:
    if ((request.getparameter(constants.cancel_property) != null)
         (request.getparameter(constants.cancel_property_x) != null)) {
        request.setattribute(globals.cancel_key, boolean.true);
    }

六、下面說(shuō)明這個(gè)request是如何真正被處理的,下面的方法都是在requestprocessor中定義。

    通過(guò)processvalidate(httpservletrequest, httpservletresponse, actionform,
    actionmapping)判斷request中的parameter是否合法。如果合法就返回true,否則取消這次請求,
    并且返回到指定的輸入頁(yè)面。它判斷合法的過(guò)程是:如果這次的請求被取消,那么直接返回true;
    如果沒(méi)有要求對request中的parameter進(jìn)行合法性檢驗,也直接返回true;最后通過(guò)調用
    form.validate(mapping, request)執行檢驗,如果返回的actionerrors為null,那么代表通過(guò)
    檢驗,返回true,否則取消這次request。取消的過(guò)程是:如果這個(gè)請求是multipart類(lèi)型的,那么
    要對這個(gè)multipartrequesthandler進(jìn)行回滾;而后,獲取當前的actionmapping的input值,即在
    config xml 中<action.../>定義的input屬性。如果actionmapping沒(méi)有這個(gè)input值,那么調用
    response.senderror(...)方法,然后返回false;如果存在,就保存驗證出錯信息到request中,
    key為globals.error_key,跳轉到input所指定的地址中。

    processforward(httpservletrequest, httpservletresponse, actionmapping)以及
    processinclude(httpservletrequest, httpservletresponse, actionmapping)分別通過(guò)執行
    requestdispatcher.forward(request, response) 以及 requestdispatcher.include(request,
    response)實(shí)現對頁(yè)面的跳轉。
    
    但是如果當前的請求還有其它操作要執行,那么actionmapping中的include或者forward屬性值就
    會(huì )為空。這時(shí)需要通過(guò)調用processactioncreate(httpservletrequest, httpservletresponse,
    actionmapping)方法根據config xml文件的配置信息生成一個(gè)action類(lèi),然后通過(guò)
    processactionperform(...)調用生成的action中的execute(...)方法。最后根據execute(...)
    方法返回的actionforword類(lèi),執行跳轉。在整個(gè)過(guò)程中有一個(gè)url的計算方法,這個(gè)將在下一篇
    中說(shuō)明。


七、對actionmaping結構的說(shuō)明:
    在actionconfig為保存moudle action屬性的一個(gè)javabean,它有以下屬性:
    * boolean configured 這個(gè)對象的所有屬性是否已經(jīng)被配置完。如果已經(jīng)完成,那么在改變其中
      任何屬性都會(huì )拋出illegalstateexception("configuration is frozen")
    * moduleconfig moduleconfig 本actionconfig類(lèi)所屬于的moduleconfig。
    * string attribute request范圍 或者 session范圍 的屬性名稱(chēng),我們將通過(guò)這個(gè)屬性名稱(chēng)來(lái)
      獲取相應的form bean,注意,這個(gè)屬性與form bean中定義的名稱(chēng)是不一樣的。注意以下的方
      法:
      public string getattribute() {
          if (this.attribute == null) {
              return (this.name);
          } else {
              return (this.attribute);
          }
      }
    * string forward 調用requestdispatcher.forward()方法時(shí)所需要的上下文相關(guān)的地址。
    * string include 調用requestdispatcher.include()方法時(shí)所需要的上下文相關(guān)的地址。
    * string type action類(lèi)的類(lèi)全名,如果上面的兩個(gè)屬性都沒(méi)有定義的話(huà),就會(huì )用它來(lái)處理
      request。
    * string input 如果輸入數據沒(méi)有通過(guò)驗證,將會(huì )以這個(gè)值為地址,跳轉到相應的頁(yè)面。
    * string multipartclass multipartrequesthandler實(shí)現類(lèi)的全名
    * string name 與本類(lèi)相關(guān)的 form bean 的名稱(chēng)。
    * string parameter 用于struts的擴展,存儲其它的配置信息。struts自己不會(huì )用到這個(gè)屬性。
    * string path 上下文相關(guān)的地址,這個(gè)地址為下一個(gè)將會(huì )進(jìn)入的地址,這個(gè)地址必須要以"/"
      開(kāi)頭。如果使用了extension mapping的話(huà),這個(gè)地址將不會(huì )帶有擴展名。
    * string roles 一個(gè)以","分隔的角色名稱(chēng)。這些角色將會(huì )有權限訪(fǎng)問(wèn)這個(gè)request。
    * string scope 缺省為session。
    * string prefix,string suffix后綴和前綴。
    * boolean unknown 標志當前的actionconfig類(lèi)是否是為了未知的request path而準備的,
      actionmappings將會(huì )根據這個(gè)標志返回這個(gè)actionconfig。
    * boolean validate 是否調用validate()方法進(jìn)行數據校驗。    

    actionmapping 繼承自 actionconfig,它增加了從moduleconfig查找actionforword的方法。同
    時(shí)它還提供了從moduleconfig查找exceptionconfig的方法,如果找不到,會(huì )通過(guò)
    type.getsuperclass()方法,根據父類(lèi)的類(lèi)名稱(chēng)繼續查找,直到最后。

八、關(guān)于request.getservletpath()的解釋?zhuān)?br>    request.getservletpath() 的返回值就是在下面url中定義的值,比如如果按照下面的定義
    <url-pattern>
      *.do
    </url-pattern>
    那么:
    http://localhost:8080/servlet/go.do ---------->/go.do
    http://localhost:8080/servlet/where/go.do ---------->/where/go.do
    這里有一個(gè)小常識,如果
    <url-pattern>
      /where/*.do
    </url-pattern>
    那么地址中只有http://localhost:8080/servlet/where/*.do有效(tomcat 4.0)


    在actionconfig為保存moudle action屬性的一個(gè)javabean,它有以下屬性:
    * boolean configured 這個(gè)對象的所有屬性是否已經(jīng)被配置完。如果已經(jīng)完成,那么在改變其中
      任何屬性都會(huì )拋出illegalstateexception("configuration is frozen")
    * moduleconfig moduleconfig 本actionconfig類(lèi)所屬于的moduleconfig。
    * string attribute request范圍 或者 session范圍 的屬性名稱(chēng),我們將通過(guò)這個(gè)屬性名稱(chēng)來(lái)
      獲取相應的form bean,注意,這個(gè)屬性與form bean中定義的名稱(chēng)是不一樣的。注意以下的方
      法:
      public string getattribute() {
          if (this.attribute == null) {
              return (this.name);
          } else {
              return (this.attribute);
          }
      }
    * string forward 調用requestdispatcher.forward()方法時(shí)所需要的上下文相關(guān)的地址。
    * string include 調用requestdispatcher.include()方法時(shí)所需要的上下文相關(guān)的地址。
    * string type action類(lèi)的類(lèi)全名,如果上面的兩個(gè)屬性都沒(méi)有定義的話(huà),就會(huì )用它來(lái)處理
      request。
    * string input
    * string multipartclass multipartrequesthandler實(shí)現類(lèi)的全名
    * string name 與本類(lèi)相關(guān)的 form bean 的名稱(chēng)。
    * string parameter 用于struts的擴展,存儲其它的配置信息。struts自己不會(huì )用到這個(gè)屬性。
    * string path 上下文相關(guān)的地址,這個(gè)地址為下一個(gè)將會(huì )進(jìn)入的地址,這個(gè)地址必須要以"/"
      開(kāi)頭。如果使用了extension mapping的話(huà),這個(gè)地址將不會(huì )帶有擴展名。
    * string roles 一個(gè)以","分隔的角色名稱(chēng)。這些角色將會(huì )有權限訪(fǎng)問(wèn)這個(gè)request。
    * string scope 缺省為session。
    * string prefix,string suffix后綴和前綴。
    * boolean unknown 標志當前的actionconfig類(lèi)是否是為了未知的request path而準備的,
      actionmappings將會(huì )根據這個(gè)標志返回這個(gè)actionconfig。
    * boolean validate 是否調用validate()方法進(jìn)行數據校驗。    

    actionmapping 繼承自 actionconfig,它增加了從moduleconfig查找actionforword的方法。同
    時(shí)它還提供了從moduleconfig查找exceptionconfig的方法,如果找不到,會(huì )通過(guò)
    type.getsuperclass()方法,根據父類(lèi)的類(lèi)名稱(chēng)繼續查找,直到最后。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
JR 精品文章 - 使用Timmer使Struts修改struts-config.xml文...
Go 語(yǔ)言?xún)戎玫?Handler
struts2 處理請求流程分析(結合源碼)2
struts源代碼閱讀(struts 初始化)
擴展struts
Struts第一天
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久