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

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

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

    table

    對struts2的底層源碼的解讀

    此問題網上很多人在討論,至今還是沒有很好的解決方案,在我對源碼進行解讀后,現在已經有個很好的解決方案,業務是用戶注冊(含復選框),用戶注冊驗證出錯后,錯誤信息的要顯示在相應控件的后面,同時要讓請求選中的復選框處于選中狀態。希望您往下看,說不定會小有收獲哦!!

    步驟:

    1)開發工具設置

       a)工程編碼utf-8

       b)文件代碼樣式javaxml

       c)文件編碼格式utf-8jsphtmljs

    2)創建目錄結構

    3) 搭建struts2的環境,

    a)    導入jar

    參考struts2.1.8下的app下的struts2-blank-2.1.8項目,拷入基本的jar

    ==========================================================

    struts2-core-2.x.x.jar :Struts 2框架的核心類庫

           xwork-2.x.x.jar :XWork類庫,Struts 2在其上構建

    ognl-2.6.x.jar :對象圖導航語言(Object Graph Navigation Language),struts2框架通過其讀寫對象的屬性

           freemarker-2.3.x.jar :Struts 2UI標簽的模板使用FreeMarker編寫

           commons-fileupload-1.2.1.jarcommons-io-1.3.2.jar這兩個jar是用于文件上傳

    ===========================================================

           b)修改web.xml配置文件、添加struts.xml文件

           c)啟動項目測試index.jsp界面輸出

    3)注冊頁面

    頁面的源碼如下:粗心了點沒有實現純國際化


    相信您已經推斷出我的項目大致部署,我這里就簡要描述下:

    配置文件:struts.xmlstrus-user.xml基于模塊化配置,UserAction-registerUser-validation.xml在執行UserActionregisterUser方法時進行校驗

    屬性文件:有全局的國際化文件和user模塊的國際化文件

    類:UserActionUserBeanHobby

    工程目錄


    Struts.xml文件


    UserAction




    工程目錄
    Struts.xml文件
    UserAction類
    第一個問題出現了,如下圖:
    說明
    很多人都是對此很煩惱,struts2使用的默認主題是xhtml,查看html頁面的源碼發現,它給我們生成了表格布局,所以界面比較整齊,但在提供便利的同時,也帶來些煩惱,就是錯誤提示出現的位置。
    解決方案
    1)把主題設為theme=simple,自己去控制布局,
    2)struts使用freemarker模版技術,為我們標簽生成了html代碼,所以我們通過修改模版設置錯誤信息提示的位置。
    解讀源碼了:
     
    a: <s:textfield/>這是strus2給我們提供標簽,所以我們查看官方文檔得知struts-tags.tld在struts-core.jar文件里,每個標簽都是一個java類,只是該類extends TagSupport,我們查看TextFieldTag類,其實有經驗的人都能猜的八九不離十,您肯定是的。
    查看TextFieldTag類
    發現它沒有doStartTag()方法,所以猜肯定在父類里定義了,查看AbstractUITag,這個類里也沒有doStartTag()方法,這個類是所有UI標簽的父類,里面定義了標簽的屬性
    繼續查看父類,
    該類有doStartTag()方法,
    我們查看得知,container容器注入了component組件,組件會話出html文本,所有我們需要查看著個組件的具體實現類,在TextFieldTag里面發現
    查看Component具體類TextField,
    查看注釋得知該類構建html文本,但為什么TextField沒有繼承Component類呢?一猜就是UIBean繼承了,查看
    果然是繼承了Component,學框架思想最重要的是看別人的注釋,因為注釋是別人思想的表達,這個類負責通過模版構建html文本,所以我們最重要的是找到模版的位置,這個我也是大概看懂,畢竟還沒達到水平,相信您已經達到,大致意思是找這些屬性值,從而定位到ftl模版文件
    struts.ui.theme=xhtml
     
    struts.ui.templateDir=template
    struts.ui.templateSuffix=ftl

    如:<s:checkbox/> 找/template/xhtml/checkbox.ftl模版文件,類推<s:textfield/>,在strus2-core.jar下找textfield.ftl,發現是text.ftl,打開我們查看:

     
    包含三個模版,controlheader.ftl又包含controlheader-core.ftl文件,該文件才是核心,
    現在我們要修改controlheader-core.ftl、controlfooter.ftl文件,把錯誤信息放到controlfooter.ftl里面,我們可以有兩種方式修改:
    1) 拷貝出兩個文件,修改后再壓縮進去(嚴重不建議!)
    2) 既然有這樣的需求,strus2團隊肯定考慮到了,這讓我實在太佩服他們了,每個細節考慮的都是那么周到,看官方文檔
    Strus2團隊提出了模版的加載、選擇模版目錄、選擇主題、擴展主題。我們想讓框架加載我們的模版文件,所以我們點擊Template Loading鏈接查看,
     
    意思大概是,首先加載應用程序路徑下模版文件,然后去加載classpath下的模版文件,如果需要覆蓋某模版,拷貝修改后放置應用程序下,那樣將首先加載。本人英語不是太好,如有出處,請見諒!
    現在我們需要把兩個ftl文件放置application下,有什么格式要求嗎?
    本章里strus2團隊還給我們提供很多建議,建議我們不要隨便更換模版引擎,如要修改ftl文件最好把源文件拷貝出來加以修改,不要自己手工重寫,以防止出錯。
    相信也不用解釋了,格式為:/template/$theme/$template.ftl.
    所以我們只要在Web-Root下創建/template/xhtml文件夾,拷貝controlheader-core.ftl、controlfooter.ftl文件再加以修改。
    本人對于freemarker語言不是很了解,但掌握了思想,這種增增刪刪的操作還是可以應付的,經過幾輪修改,總于搞定了。
    ----------------------------------------------------------------------------------------------------
    第二個問題:
    先對strus2的默認攔截器原理說下
    官方文檔這兩行最能表達我的意思,excludeMethods參數是設置該攔截器忽略哪些方法,下面反之。這簡單原理相信您非常了解了,來看下我們這里出現的情況吧!
    這是最普遍的業務邏輯,
    這是strus-user.xml配置文件里的registerUser*.action配置:
    情況一:
    我們按此配置運行,我們不填用戶名注冊,結果出現如下情況:
    說明:
    為什么出現無法顯示網頁呢?我們注冊首先被validate攔截器攔截后,UserAction-registerUser-validation.xml驗證用戶名不能為空,經過workflow攔截器,發現驗證出錯了,所以跳轉input試圖,我們input沒有配置type,默認是dispatcher,我們這樣轉發的話,則不再被strus2的攔截器攔截,相當于瀏覽器訪問registerUserUI靜態資源,因為壓根沒有,所有tomcat容器無法訪問,則出現無法顯示網頁
    情況二:
    好的我們現在修改input結果的type屬性為redirect,
    我們選中兩個愛好,提交返回界面如下:
    開始選中的被取消了,并且沒有“用戶名不能為空”的錯誤信息。
    說明:
    為什么會錯誤信息沒了呢?同樣經過validate、workflow攔截器后,跳轉input試圖,一但我們重定向,則strus2框架會為我們創建一個新的UserAction對象,則fieldErrors、UserBeanhobby數組都為null了,所以錯誤信息、開始選中的都顯示不出來了。
    情況三:
    相信您已經有解決方案了,把input試圖的type設為chain類型,chain類型的作用是,讓該請求重新被攔截器攔截,好我們來修改:
    我們同樣不填用戶名,選中兩個愛好,點擊注冊后,發現如下結果:
    意思大概是:發現一個無限遞歸調用。
    說明:
    怎么會出現這樣無限遞歸呢?哪里在遞歸調用?我們來分析一下流程,當經過validate、workflow攔截器后,跳轉input試圖,此時type=chain,所以我們看下設置為chain類型后,struts2到底都干了些什么?在官方文檔Action Chaining一章里講解到,
    大概意思是如果你要拷貝當前的action屬性到當前chain上的action,你需要應用Chaining攔截器,該攔截器會拷貝請求上的parametersvalue stack傳遞到目標action,原始的action會保存valueStack,允許目標action訪問前面所有action的valueStack作用域上的屬性,同樣對于chain的result結果試圖如jsp、velocity界面同樣可以訪問這些屬性。
    =====================================================
    所以當我們以chain方式訪問registerUserUI.action,原先action的valueStack上的fieldErrors同樣被拷貝到當前UserAction對象fieldErrors字段里,在經過workflow攔截器后,又發現有錯誤,同樣調用input試圖,進而又去調用registerUserUI.action,經過workflow攔截器后,又發現有錯誤,又去調用input試圖,進而遞歸調用。
    現在該怎樣解決呢?我們要做的就是,讓他調用registerUserUI.action時被workflow攔截器攔截后,不再驗證是否有錯誤,前面說到過excludeMethods參數,我們查看workflow攔截器
    發現他忽略input方法,所以我們加上這樣的配置:
    修改UserAction的registerUserUI方法為input,ok了!我們運行同樣不填用戶名、選中兩個愛好提交,運行結果為:
    注意:
    雖然chain方式對于完成這種業務很方便,官方提示我們謹慎使用,過度使用會造成程序的代碼混亂,到時還是根據業務來決定。

    posted on 2009-12-24 15:42 小卓 閱讀(2098) 評論(2)  編輯  收藏 所屬分類: otherstruts

    Feedback

    # re: 對struts2的底層源碼的解讀 2011-05-27 17:41 easy518網址導航

    http://www.easy518.com  回復  更多評論   

    # re: 對struts2的底層源碼的解讀 2012-08-13 16:50 wew

    fsdf  回復  更多評論   


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


    網站導航:
     
    主站蜘蛛池模板: 国产在线观看xxxx免费| 特级aaaaaaaaa毛片免费视频| 暖暖在线视频免费视频| 亚洲熟妇无码另类久久久| caoporn国产精品免费| 国产午夜亚洲精品理论片不卡| 牛牛在线精品观看免费正| 亚洲区日韩区无码区| 在线免费观看h片| 亚洲国产精品久久久久久| 亚洲毛片在线免费观看| 亚洲91精品麻豆国产系列在线| 免费无码A片一区二三区| 亚洲变态另类一区二区三区| 免费在线视频一区| 中文字幕免费观看全部电影| 亚洲av永久无码精品漫画| 天天影院成人免费观看| 一本色道久久88—综合亚洲精品| 日产乱码一卡二卡三免费| 一级毛片无遮挡免费全部| 国产亚洲一区二区三区在线| 99免费在线观看视频| 亚洲精品乱码久久久久久蜜桃图片 | 亚洲一级毛片免费看| 亚洲精品国产精品| 亚洲国产精品人人做人人爱| 人人玩人人添人人澡免费| 亚洲午夜精品一区二区公牛电影院| 精品久久久久久久免费加勒比| 精品国产免费人成网站| 久久夜色精品国产噜噜亚洲AV| 性色av免费观看| 国产精品免费观看视频| 亚洲日韩乱码久久久久久| 国产成人无码a区在线观看视频免费| 国产精品hd免费观看| 亚洲中文字幕久久精品无码2021| 国产女高清在线看免费观看| 免费精品一区二区三区第35| 精品亚洲456在线播放|