尚硅谷STRUTS2視頻學習筆記


  上一個月一直在學習STRUTS2,學習的是尚硅谷佟剛老師的視頻,因為很喜歡佟剛老師的聲音,而且他講的很細,筆記做的也多,基本上是照着他的視頻完整的敲了一遍代碼,下面就把學習到的知識梳理一遍,最后把項目分享一下,有需要的可以下載一下。佟剛老師是新建了很多個工程,而我是把所有的內容放在一個工程中的,所以可能有些亂。

  工程的結構:

自己也照着所說的筆記自己敲了一遍。所以不但有代碼,還有note.txt文件。

想看的話可以去尚硅谷官網去下載一下相關視頻。

尚硅谷視頻

下面就說一說我印象深刻的一些東西吧。

首先上一張圖

這就是處理一個STRUTS2請求的流程

STRUTS2的核心是一個Filter,請求會最先通過這個Filter,然后進行相應處理,首先通過ActionMapper判斷請求是否是struts2請求,如果是struts2請求,那么會產生一個action的代理對象,他會與ConfigurationManager進行交互處理struts.xml配置文件,確定請求的是哪一個action,然后還會生成actionInvocation對象,該對象的invoke方法會調用攔截器棧,然后在攔截器中也會調用actionInvocation的invoke方法,最終的結果就是形成如圖中間所示的interceptor...action...result...interceptor...這樣的一串調用,產生的結果中的數據在頁面中的標簽中使用,此時也會被解析,然后就會返回給前台頁面一個結果。

 下面就具體說說STRUTS2的相關內容。

1. OGNL相關標簽:

1)通用標簽

主要有8個,

可以看項目中的common-tag.jsp文件或百度查看相關用法。

2)表單標簽

主要有10個

可以看項目中form-tag.jsp或百度了解相關用法。

可以通過%{xxx}強制進行ognl解析,可以通過加單引號的方式強制使用字符串。可以通過#{key:value,key:value...}的形式構造map,在request,application等非根對象前加#進行調用。

2. 值棧的概念

簡單的說:值棧是對應每一個請求對象的輕量級的內存數據中心。

Struts2中一個很激動人心的特性就是引入了值棧,在這里統一管理着數據,供Action、Result、Interceptor等Struts2的其他部分使用,這樣一來,數據被集中管理起來而不會凌亂,大大方便了程序編寫。

Struts2中關於值棧的另外一個很激動人心的特性就是:大多數情況下,你根本無需關心值棧,你不用管它在哪里,不用管它里面有什么,你只需要去獲取自己需要的數據就可以了。也就是說,你可以隱式的使用值棧。

當然,如果編寫自定義的Result或攔截器等較復雜功能的時候,還是需要顯示訪問值棧的,因此,還是需要你掌握值棧的知識。

可以通過<s:debug></debug>標簽查看值棧里的信息

值棧分為MAP棧和對象棧,MAP棧如存放application,session,request,parameters的MAP,對象棧存放如action對象中的屬性,如果頁面上需要一個屬性,他會按如下順序進行查找

page,request,對象棧,session,application,其中在值棧中會先從棧頂依次向下查找。

3. 數據的處理

struts2對前台數據的獲取十分簡單,如有一個form表單,有很多input元素,他們有不同的name,則在后台只要在相關action設置與name同名的屬性值並設置set方法即可獲取到前台的數據,而且支持復合類型,

如何支持復合類型呢,只需要實現一個ModelDriven接口,如下

則和employee對象的屬性同名的數據就會被賦給employee對象,當然數據類型要一致或可以轉換,不可以轉換的可以自定義轉換器進行數據類型的轉換,如果對數據還有進一步的要求,還可以對數據進行校驗,分為聲明式校驗與編程式校驗,這些在下面再說。

實現了modelDriven,要重寫getModel方法,該方法返回一個Employee的對象,用於接收數據,上面還實現了一個Preparable接口,這個接口的作用是彌補modelDriven接口的不足,同時還定義了一個Employee中已有的屬性employeeId,這是開發中常用到的技巧,因為getModel方法返回時employee對象還是空的,所以定義一個employeeId,他的賦值在getModel之前,這樣在getModel時可以根據這個employeeId進行一些定制,這時就要用到一個攔截器棧

paramsPrepareParamsStack

其實我們還是沒用getModel進行定制,因為我們實現了Preparable,所以通過Preparable結合employeeId進行定制,

 

paramsPrepareParamsStack如圖

在1時給employeeId賦值,在2時調用preparable的相關方法,3時調用modelDriven的getModel方法,然后employee對象相關屬性就可以被使用或賦值

我們要實現preparable的prepare方法,通過閱讀源碼可知,preparable還會調用嘗試調用(prepare+方法名)或(prepareDo+方法名)的方法,所以在某個action調某個方法時,可以定義如上命名的一個方法,使用在1階段被賦值了的屬性,進行相應定制employee等復合對象操作,而在getModel中不做其它操作, 直接返回employee等復合對象。

這樣我們通過使用paramsPrepareParamsStack攔截器棧中的1,2,3,實現了對action的定制,

這有什么用,舉個代碼里的例子,如我們想編輯某一個employee,前台只傳了一個employeeId過來(后台對應方法為edit()),那么我們可以增加一個prepareEdit()方法,在獲得employeeId之后,在prepareEdit中通過id查詢數據庫獲得該employee的完整信息,將信息傳給employee對象,然后在edit方法中就可以使用employee對象返回給前台編輯頁面。

再如新增時(add()方法),可以通過prepareAdd給employee對象new一個對象,然后通過getModel返回employee對象,在add方法中employee對象就會有前台新增的數據,從而可以進行新增的操作。

 

這里面為了定制並沒有使用prepare方法,這個方法一般情況下調用每個方法都會執行,要讓他不執行,需要在STRUTS.XML文件中配置一個屬性,如下圖

按圖中紅框處使用

這就講到了struts2的配置文件。

4. struts2.xml文件

文件以包為單位進行組織,包可以有命名空間,到頁面上也就是一段路徑

 要繼承一個struts-default包以使用繼承的包里的相應功能。

 可以定義一些constant常量以配置一些內容。這些constant常量可以從struts2-core-2.3.15.3.jar中的default.properties中查看。

還可以在包中定義一些全局的異常以及異常轉向的頁面。

struts.xml中主要就是包及包中的action

如果一個action不定義class那么會有一個默認的class叫做ActionSupport,如果不定義method會有一個默認的method叫做execute,如果result不定義name會有一個默認的name叫做success,如果result不定義type會有一個默認的type叫做dispatcher(轉發)。action中還可以使用通配符,如上圖,使用通配符后可以在method,result及返回的頁面中通過{1}{2}...來獲取通配符代替的內容。

如果我們想修改某個攔截器棧的內容可以通過上圖的方式,即自己定義一個攔截器棧,在我們自定義的攔截器棧中對原攔截器棧進行修改,最后使用我們新定義的攔截器棧即達到了對原有攔截器棧的修改使用。

那如何在原有攔截器棧的基礎上使用其它的攔截器呢,可以通過上圖的方式,即通過interceptor-ref引用要使用的攔截器,不要忘了加上defaultStack默認攔截器棧。

,

result的類型常用的有上面幾種,dispatcher是默認的轉發到頁面,redirectAction是重定向到action,也可以通過redirect實現,redirect是重定向,chain是轉發到action,stream用於文件下載。

 5. 獲取struts或原生的作用域的對象application, session, request, parameter

1)獲取struts的相關對象,有兩種方法,

1. 通過ActionContext。

如下

2. 通過實現相應的xxxAware接口。

上面以application作為示例。

2)獲取原生對象的方法

1. 通過ServletActionContext

session和parameter可以從request中獲取

2)通過實現ServletxxxAware接口

6)i18n國際化

 

可以對Action或Model中的屬性進行國際化配置,有三種方式,只對某個ACTION進行配置,對整個包下的ACTION進行配置,對整個項目進行配置。需要實現ActionSupport接口。

1)對某個ACTION進行配置:

 如圖中2:在ACTION中可以通過getText()方法獲取相關國際化數據,命名規則為actionName_language_country.properties

2)對整個包進行配置:

如圖中1所示,命名規則為package_language_country.properties

3)對整個項目進行配置

命名規則:name_language_country.properties

然后要在struts.xml文件中進行配置:

文件中可以使用OGNL表達式或者占位符,占位符在頁面上進行填充

除了request_locale之外,還有一個request_only_locale,顧名思義,它的作用范圍只限在當前頁面。

 7.自定義攔截器

可以實現AbstractInterceptor抽象類或Interceptor接口,繼承抽象類的好處是抽象類中的大部分方法已經有了默認的實現,我們自己只需要實現某個核心的接口就可以了。而實現某個接口則要實現其中的所有的方法。

實現的方式如上圖,中間要調用一下invocation.invoke()方法,使可以調用攔截器棧中的其它攔截器,然后在之前和之后可以寫自己的代碼,之前的代碼會在調用ACTION之前調用,之后的代碼會在調用ACTION之后調用。

光寫好了類還不行,還要進行相關的配置才可以使用。

如圖,先聲明一下這個攔截器,然后就可以進行使用啦!

8.自定義轉換器

 

可以繼承StrutsTypeConvertor,重寫其中的convertFromString,convertToString,或者實現TypeConverter

圖中convertFromString中的arg0是上下文對象,可以獲取一些上下文參數,arg1是要轉換的字符數組,arg2是后台對應的數據類型

 convertToString中的arg1是前台所需的對象,因為前台展示的是字符串,所以要進行類型轉換或定制顯示的內容。

 寫好了類當然要進行相關配置才可以使用啦。

也有兩種配置方式,如果是針對某一個action,可以在同包下建立一個actionName-conversion.properties文件,如果是針對整個項目,可以在項目的根路徑下新建一個名為xwork-conversion.properties的文件

兩種文件的內容如下

java.util.Date=atguigu.type.convertor.DateConvertor

大致定義了對某種類型使用某種轉換器。

還有自定義錯誤消息與錯誤消息的顯示格式可以參看項目中的相關內容。

大致自定義錯誤消息就是在MODEL或ACTION的同一個包下新建一個actionName.properties的文件,內容為invalid.fieldvalue.xxxx=xxxx,第一個xxxx是字段名,第二個xxxx是字段轉換出錯時顯示的錯誤消息。

9. 校驗器

校驗器分為聲明式校驗器與自定義的校驗器,聲明式校驗器又分為字段校驗與非字段校驗,

聲明式校驗的相關內容可以參見:struts-2.3.16.1/docs/WW/docs/validation.html

如圖是一個字段校驗,如果一個ACTION類的不同方法對應的不同ACTION有不同校驗規則,那么可以如圖定義多個配置文件,配置文件的命名規則為actionClassName-actionName-valudation.xml,這樣相關的action請求就會使用相關的校驗規則,如果還有一個actionClassName-validation.xml的配置文件,那么該ACTION類的所有action請求都會使用該校驗規則。

上圖應用了一個非字段驗證和一個自定義的驗證

關於自定義驗證:

首先新建一個類繼承FieldValidatorSupport或ValidatorSupport,

 

其中format屬性對應配置文件中的format參數,只要提供一個set方法,就可以進行使用,

validate方法的寫法可以參照其它校驗器,如何找到其它校驗器呢?在xwork-core-2.3.15.3.jar中包com.opensymphony.xwork2.validator.validators下default.xml文件定義了默認的校驗器。

主要是獲取字段名,通過字段名獲取字段值,對字段值進行校驗,校驗不通過時調用方法增加字段錯誤。

 類寫好了使用前要先配置,

在工程根目錄下新建一個validators.xml,內容如下

然后就可以在相關的validation配置文件中使用我們定義的校驗器了。如上面對idCard校驗器的使用。

10. 文件的上傳下載

1)文件的上傳

以上傳多個文件為例

這一組文件標簽使用同一個name,然后在java文件中

使用一個List接收,同時還定義了兩個新的屬性,nameContentType,nameFileName,它倆會自動獲取上傳文件的內容類型和文件名,因為上傳多個文件,所以用的List,

然后就可以把File對象的列表給保存起來啦。

STRUTS2的文件上傳實際上使用的是APACHE COMMONS的Fileupdoad組件。

我們可以通過修改FileUploadInterceptor攔截器修改文件上傳的配置,maximumSize,allowedTypes,allowedExtensions,還可以配置一次允許上傳的最大大小,

配置方式如下:

當上傳文件出錯時,我們還可以自定義國際化的錯誤消息

在國際化文件中配置上面的內容,后面的占位符會顯示出錯文件的相關信息。

 2)文件的下載

文件的下載要用到結果類型stream,文件下載時要配置一些參數,這些參數可以在struts.xml文件中進行配置,也可以在下載的action中通過屬性的方式進行配置,只需要提供屬性的get方法,

 

上面就通過在類文件中獲取一部分配置項,在配置文件中配置一部分配置項的方式進行的下載操作。

 上面是可以進行配置的七項內容。

 11.防止表單的重復提交

重復提交有下面三種情況

1)多次點擊提交按鈕

2)已經提交成功,按回退之后,再點擊提交按鈕

3)在控制器響應頁面的形式為轉發情況下,若已經提交成功,然后點擊”刷新(F5)“

下面兩種情況不算重復提交

1)若刷新表單頁面,再提交表單不算重復提交

2)若使用的是redirect的響應類型,已經提交成功后,再點擊刷新不會重復提交

 解決表單重復提交可以使用token或者sessionToken攔截器。

需要在頁面上表單中使用s:token標簽,具體的原理可以看相關視頻,

然后在struts.xml中使用相關的攔截器,

 

有一點需要注意,如果使用的是token攔截器,則重復提交時會跳轉到一個錯誤頁面,所以要配置一個name為invalid.token的result,而如果使用tokenSession,則重復提交不會有任何結果,就像什么都沒有發生過一樣。

 以上就是我學習的主要內容,但不是全部,視頻中還有大量對源碼的講解和其它細節,可以參看視頻了解。講得沒什么新意,就是把視頻里的東西復述了一下,因為所知有限,也沒有什么延伸,新學習STRUTS2,僅做一個記錄,給同樣是新手的人看一下大致對STRUTS2有一個了解,可以初步使用的樣子。

我的項目代碼如下:

項目代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM