struts2流程以及源码解析

上传人:m**** 文档编号:202415784 上传时间:2023-04-22 格式:DOCX 页数:14 大小:451.57KB
返回 下载 相关 举报
struts2流程以及源码解析_第1页
第1页 / 共14页
struts2流程以及源码解析_第2页
第2页 / 共14页
struts2流程以及源码解析_第3页
第3页 / 共14页
点击查看更多>>
资源描述
1.1Struts2 请求处理1. 一个请求在 Struts2 框架中的处理步骤:a) 客户端初始化一个指向 Servlet 容器的请求;b) 根据 Web.xml 配置,请求首先经过 ActionContextCleanUp 过滤器,其为可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助(SiteMeshPlugin ),主要清理当前线程的 ActionContext 和 Dispatcher;c) 请求经过插件过滤器,如:SiteMesh、etc等过滤器;d) 请求经过核心过滤器FilterDispatcher,执行doFilter方法,在该方法中, 询问ActionMapper来决定这个请求是否需要调用某个Action ;e) 如果ActionMapper决定需要调用某个Action,则ActionMapper会返回个 ActionMapping实例(存储Action的配置信息),并创建ActionProxy( Action 代理)对象,将请求交给代理对象继续处理;f) ActionProxy 对象根据 ActionMapping 和 ConfigurationManager 询问框 架的配置文件,找到需要调用的 Action 类;g) ActionProxy对象创建时,会同时创建一个ActionInvocation的实例;h) ActionInvocation 实例使用命名模式来调用,在调用 Action 的过程前后, 涉及到相关拦截器(Intercepter )的调用;i)旦Action执行完毕,Actioninvocation实例负责根据struts.xml中的配 置创建并返回Result。Result通常是一个需要被表示的JSP或者FreeMarker 的模版,也可能是另外的一个Action链;j)如果要在返回Result之前做些什么,可以实现PreResultListener接口, PreResultListener可以在Interceptor中实现,也可以在Action中实现;k)根据Result对象信息,生成用户响应信息response,在生成响应过程中可 以使用Struts2框架中继承的标签 在此过程中仍会再次涉及到ActionMapper ;2.Struts2 请求处理示意图:Co nif lg uratlon MnnEigorH it pSar w 1 1 口萱Aat ionto mlt F i-IEiorisHttpiSiBrvrOTRiftiaipgn 毎酸Aataon ActionInvocsHEoo J書C Rsu ItTmplnw1.2Struts2 请求处理源码分析 当用户向Struts2发送请求时,FilterDispatcher的doFilter()方法自动调用, doFilter()方法处理请求过程,如下:1. 创建值栈对象 stack;2. 创建Action上下文对象;3. 对请求进行重新封装,此次封装根据请求内容的类型不同,返回不同的对象:如果为 multipart/form-data 类型,则返回 MultiPartRequestWrapper 类型 的对象,该对象服务于文件上传,否则返回 StrutsRequestWrapper 类型的对 象,MultiPartRequestWrapper 是 StrutsRequestWrapper 的子类/而这两个 类都是HttpServletRequest接口的实现。4. 通过 actionMapper.getMapping()获得 ActionMapping 对象,Action 的 配置信息存储在ActionMapping对象中(Action的配置信息Action的name、 namespace和要调用的方法method)。相关代码如下图所示:public ActionMapping gtMapprng(HttpervletReqliest request, ConfigurationManager config ManagersActionMapping nriappEng = new Acti&niVlJppingQ;fj 1.彳孚穿腾爭搭迳卸 UKI , & : lesiAtcfoti onWOfSem icclon a -=) ? urL-substri ng(C. indeicOfSemi co Ion) : uri; / 2.図降ST辰名.恣认IT雇窖为Adfdn uri - dropExtension(ujL mapping):if (uri = = nuN) r*turn twH:/工JAurESfcfi中翼常出山icn的n白制m储口.mypareNameAndNamespaee(urir mappirtq, onffgManaorJH 4,将胡学碁魏中釣靈StJE曲*handlespecialParamtersirquest, mapping);/ S. ifl黑Act泊n的c吕ee陆画蝕奇出来固挺底回if (mapping.getNameQ = null)( return riEI;fl 6.匙理书如怕ftA EP n! EG th Cd IS我的胥壊盜催pa nseAct tenpp i n g;return mapping;以上代码,活动图如下:Q WURI j仪収!左酬命件辭itkm君唧5. 如果 getMapping()方法返回 ActionMapping 对象为 null ,J则FilterDispatcher认为用户请求不是Action,此时FilterDispatcher会首先分析: 如果请求以/struts开头,会自动查找在web.xml文件中配置的packages初始 化参数FilterDispatcher会将packages参数值包下的文件当作静态资源处理, 即直接在页面上显示文件内容。如果用户请求的资源不是以/struts开头一可能是.jsp文件也可能是.html文件, 则通过过滤器链继续往下传送,直到到达请求的资源为止。6.如果getMapping()方法返回有效的ActionMapping对象贝U被认为正在请 求某个 Action,将调用 Dispatcher.serviceAction(request,response, servletContext,mapping) 方法。以上六步,相关代码如下图所示:Hnp5eni-;eifieqjestiBquKt = (HnpServIe 佩 qu 创 哋 只師矗丽卅苗阳唯儕w卩同二Http4w etRei|K?n5e)T; Seryl etfontert wrYlettanlort = getSeniIeiContextu:翩问 ti 昭 Key = FMD踊 tcher/oFi 愉:t叽#1脚備熱誡ValJeSlack staci 主血悶 KheugEtCont渝已如 etn$tdns(V咖眄Uckhctoryr 由斑阳悒四 ue噪灵嗣湫隔第例巴測OR捌; return手乱翌diHcs费三-孝器鳶豊号 ifl-ps-rfi一VJ-屠孟养“畐昙峑一一垦屯蛊1雲If 一-蛊ispa霑昼算ufwn 国亠-=if籃RKM応官宴邕生smjal- 主賠營直睾加nlliM-rr白ssgi矍-3毎吕竄鬲京曇醫潯舒 - JSS算 sjR 當岳一.養-asg.H匡三agu 奁 p.至=茴-?倉冃&R霆;isu書蛊rSK一為融圣豈68嚳言盲P/S-氨祐諮鹉亠吕 -re=-?r裁垂艺三逵洱-餐擡翼gflgma屋gt d .S3-益議尝lis离换L 一螯囂蚩sns盘召s吕亠E0E吕邑圜昔3-一冑一三乂Hr6驴M&函合(ilV.HFwkeLkm|)诣攻贸SMt趙 InHE幵扁 、汨悅看摆從规町(jMWtgD+ AK雖下咨7. 请求进入dispatcher.serviceAction(request,response,servletContext,mapping)方法 中:a) 将相关对象信息封装为 Map(如:HttpServletRequest、Httpparameters、 HttpServletResponse、HttpSession、ServletContext、ActionMapping 等 对象信息)并存入到执行上下文Map中返回执行上下文Map对象extraMap ;b) 获取mapping对象中存储的action命名空间、name属性、method属性 等信息;c)加载并解析Struts2配置文件,如果没有人为配置,默认按顺序加载 struts-default.xml、struts-plugin.xml、struts.xml ,将 action 酉己置、result 配置interceptor配置 解析并存入至config对象中返回文件配置对象config ;d) 根据执行上下文Map、action命名空间、name属性、method属性等创建用户 Action 的代理对象;e) 执行Action代理对象proxy.execute()方法,并转向结果;以上步骤相关代码,如图所示:public void sewiEeArtion-;HttpSefulelRequesi requki, HttpServlelRespcrKf response. 5erjTe(Conten! coniewt, Mi glW 叩 pi ng mapping) throws SsrvietExeption 训桁啓別遵阳舒義揃制邮i罰:HMpSendetRc申jes4. Hilf* paremetiers,日戟陷ErdetR已pomse一U 杵ttl总ssiQ血kFvIetCQnRxt.血和门隔即In扁刘扶個息齐护人珈舒上下滾Map中逅關/崭上対靱Map eicrraConteKt = rea(eCflfirl Mjp(r&qtiest, reipon m appfn. oai ewt.W lu eSt 机 k$lit)c = (VaiueStc 灯帕 il 冏.如也刚 butefvietfijClicriC cntext SJRU TS_ VAiUSTACK_iCE 片 bMleon nulStdck = it ack = nullIfCnullSUKkKAcfionCnMt -册“5“箱応网帕阿核诡;if (ctx !- null) itaCk q th etVdl utSlSikikstack !null)extrCq nlestjjd! (Action Context. VAL iJEjSTAiK, vlueSt d匚 EFa a ary a eteVlueStac klack)K宝riwg tinverKey 三request frtin Dispatch已门uyUti1Emr5(eck_p ufZXti m er Key:/ ttSmapp-irigifr.TttjactlQnftSij?.耐阳亡寤性.rn亡mod麻性龍IB色String namedte = mappirtggfftNdmfspsceOrttflng nam - aupping.etN aString method - ma ppjng.getMethadJI d拘砖解折帥ul毅iE丈炜r舸農厨人务他.VEMAifcuuls-duIIjml.H uK-pruginjonl. itmtsjml. Wactiang.fi iftuitffiS. imerc-eptorEa,墀历/幷存入至巴Mi破嶽卫.ifi回刘*ft胡撤卯卯Corbfigurationonfig 弓 on Itgufaiiori Marwger.geKaAfiguiraUonO;匪执行J:FS血0 sctiiHi誌咅兰可raarrieflEli niHrMX厚整 创強甲户自定珈ttian的代破栓AcGanPrtJJty proxy =nf ig.get anla ie rQ.geGnste 门“(&:日即 Pr?yf ac(a ry.c hssx:r?a(e ArtianProKyj附ftW” Method 朋滋规诞 kl, trut.fAlife)!requLwtAttributetServieWcttonConcext. STRUTS. VALUfSTACiCY, proJv.getinvocaiionO.gelStackOk 丿/町血行p旳好単讯口诃方港”方無隔裂if (mapping.geiRnukO、null)(临jM rewt = m*pptng总戟加讪心 resLtltejifiCMl!epjDfflyjget!n.vocdtlon0;! Ih fi蚀典朝sttitefi8.执行Action代理对象proxy.execute()方法,该方法的执行,其实就是调用了 invocation.invoke()方法,如下图所示:publi e String esecuteO throws Exception (AdioriCdntexl prevraus = ActEOn 匚 ori曲ftp枫Un打怙MO:AtlionC oritekt.回Caw熾 n vocit iari .getlz 亡cst i 匕 rioriteirt);trytThis for the new APIreturn Requesi匚Dnixtfnplc:allInZcinENt(iiiO亡自丘口九仃亡说匚41laeString?0 public StFing calif) throws Exception return InvtKJtionjnvakC;Jretuit) Irtvott ionjnvokeO;if (deanupContexQAction Con test. setC-ofi texK previous;/9.执行invocation.invoke()方法,实现了截拦器的递归调用和执行Action的execute。方法,DefaultActionInvocation.invoke()方法中代码,如下图所示:pubA Suing inwhi ttirowiEi replion 4String p(iofileKej = i価垃1tryUtiffimertlJi ZAjf肿康赋It|卩肚血丸魯幷瘗岂当期旦if (intfirecicnrtasNxtffl IIinj13n(fflpiohlapping imeirtpGcc 闌蚯曲审西丽和 iilefteptOiUKit-* SPlng inten别讷1丹1 屈弧即:胆+亦|)?血衲爭1炳袖 UtFFimerSldc l/xinteHepto龜1申亍戈衍仍匚率方走|佈邓训期胃tKEpl冋罰【traUefdu.lAc向町Tironl加处就ULlTiffiertUt “(佃憎 ceplw雉幻讥朗細,tmWAd的仰2啟臧I件,只明皿临J.H1.吐如禹n防齢,为孑如认lch .遥删富菱 趾|邸如、虻加kiwdtbn搓葩頤卿曲0住聾容 甘%地:X :8山吹側仙蹴曲韻Mi拧if).j.加抓MEFn收时腳理或磁脚血#応;悝3抵1屹 Eff = inwItienCnl在以上代码中,并未看出拦截器的递归调用,其实是否递归调用,是由程序员来控制的,递归调用实现很简单:a) 首先看下 Interceptor 接口定义:v4ci 4rMjQF上zqjrj叶if廿9%丹咬E*?X哝祇8。巴m WSK站琢苗g;b) 所有的截拦器必须实现 intercept 方法,而该方法的参数恰恰又是Actioninvocation,所以如果在 intercept 方法中调用 invocation.invoke(), 则会继续从Action的Intercepor列表中找到下一个截拦器执行,依此递归调用 Intercepor;Struts2中的日志拦截器Logginginterceptor,如下图所示:pu blit das-s Logainanterteotor eictends Absiracthterceptor private static final Logger LOG= LoggerF actory.Logging nlerceptor.t la.55);private static final String RNISH_MESSAGE- Finishing eneirution stacSt for actran private static finat String STARr_MESSAGE Startrng execulion stack for anionpublic Siring interceptActionlmtHrtion invocation throwE Exception (ImM&s&sq 就irMK別祐1% 5 脚MF严&碎String 用刃 It = irwvwtiQn-in旳togidessag 时 irwiEti 叽芝融百盘rtu rn re lu Itc) 拦截器递归调用活动图,如下所示:心沖34513 nJilinri xlleu!J ( itpo du n?Im)|nsd-jQ4qju:白 iijoJtTX/f/i-ij 3CJSJ9 Lui ii!;n 3 :,jud)5i 1: 1 nsadjd.=人事为刍叩。dr CuijjsJuaisni 1 nsayejd (jaudisnunsays吕)=jauisii忌u说&叮ijrm甘3:u占并口 inmn甘md iqo)$Hp5in335?53j|!()XlUQUoipyasfOAUi 二 epojns-aj:土场園皿宙良矽瓜舌目鬲舸奧NlinsBB回虫丑巨gjauaisi-|l|nsayajd血章WK unsay辿手廿吕章NussEins湘9尼丄弭漳鄰方gfiii 马右兰apoDunsaj 創垄廿 uoipe 器臬上弭厂 rtOaOAui-uoiieDOAU!丑-QI在返回 Result 之前,通过 PreResultListener 实现自定义处理,常用的有两种方式:一种在 Interceptor 中实现,一种在 Action 实现,如图所示:By an Actfon3 cAc ti c-nSjpwt public Strirtg exectit-e () thri foce-ejiLi on AclKHiIiiTOcati on snveeati gd 二 AcLiorCmext. iCoBtssel 0. jetlittionlnvseatioil(): invcat i on adlFr eH&sult.Li 鼻七 g皀丁FrHsjltLi s ten电r |pyblitr voidsuit(A-ctipnlnfiiticriSlri.bg rASULLtCede) ff pp_r直ohis ipwLliejt fiee&EEsrj? bfer K&iult&V an Interceptorpubl i -c el ase Mylute rcept c&r ex t ends AliEtrctlnt arceptoz publi c String i nt er c ap t (A.c t i onlnvc cat i on invcicaLi on) thrown Except i oil _ invoc ati col 臣dJPreRe sul tLi stenerPreResultListener Q |public! vci J be for eReult A.cti anlnvocatioin iitvocatia an,Striiag resultCode) / p-Erform op er al i an R&ceasaiy before Result ese 匚 utidn):以上两种方式,大家可以发现都是通过匿名内部类的方式实现,其实还有一种方 式就是通过在拦截器中实现 PreResultListener 接口,并实现方法 beforeResult方法,即可。如下图所示:public clafii AniHiOt tic nW orfclf ro w I ratrr ccptor implaiiniMnts Intc皿亡llLREfnFFlpublic ”皿厲曰13空卑口$yjiaxtionlnTOC?lon bnvocfltlon. Slrlnig rcsultCCKle(L 1- t *-Ticel FTie-Tiriod 口 p*w Array I st Mwll-iool?-tAnnotitlijnyl l-gir-EArHrtap tiie-cdiiMeC tif frilHcdli.iiWO = 0) 4 “ rrl hcjql-s itrr sprdy 弄QrTcl feiy prip*l ty Col lecilonis .icritmec hodSL. nw CoiTipaf Jto f Metncid O ( p Li hi lie int:匚 ornpar eFvle-E hoed melhiCBd 1, Met fiod e 亡 thacl、411. 最后,通过生成 Result 完成用户响应;:土场IBS寻坚宙啟咸聊关畀茸出B寻坚轟兰冈來藝區否乙sms区爭TT-T 丁幻
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 图纸设计 > 毕设全套


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!