1. 程式人生 > >Struts2(一)

Struts2(一)

  • Struts入門
    Struts2的概念和作用:
    Struts概念:是Apache下的java開源框架,基於MVC設計模式的應用框架,本質上相當於Servlet(用來處理頁面傳送引數,處理響應),Struts最為MVC中的控制器來建立模型和檢視的資料互動,是一個基於MVC的web應用框架,是解決表現層的邏輯框架,

Web層:Servlet+JSP、Struts2、SpringMVC
Service(業務層):Spring
資料層(Dao):JDBC、DBUtils、Hibernate等Mybatis、Ibatis

核心過濾器:StrutsPrepareAndExecuteFilter

Struts2執行流程:
核心過濾器:StrutsPrepareAndExecuteFilter
(做了準備+執行操作)
會執行過濾器的初始化方法init —-載入struts內部配置檔案,包含了struts.xml檔案
執行doFilter方法:先執行攔截器(可能是多個),訪問Action類的方法,根據action名字找到對應的class和方法(利用反射機制呼叫Action類中的方法)
返回字串:
<result name ="success"></result>
返回檢視字串,對應的頁面可以訪問

這裡寫圖片描述
這裡寫圖片描述

Struts配置檔案載入:
Struts2在我們的初始化過程中,在核心過濾器呼叫init會載入配置檔案,載入6個配置檔案:
default.properties(常量檔案)
struts-default.xml(Struts核心配置,描述攔截器等)
struts-plugin.xml(Struts外掛配置—這個檔案是包含在外掛包裡面的,整合框架會用到)
struts.xml(開發者自己編寫的)Struts2配置
struts.properties:Struts2的配置(一般不用,用上一個)
web.xml:web專案的核心描述檔案

注意:以上這6個檔案的位置在哪裡?
Struts2核心包

/org/apache/struts2/default.properties
/struts-default.xml

以上的6個檔案載入過程中,後面載入的檔案會覆蓋後面載入的引數(關鍵)

以上6個檔案就是它的載入順序,

Struts.xml配置檔案解析:
package :包 :使用者管理不同的Action
name 屬性:包名:不同的package 對應不同的 name
extends 屬性:繼承檔案: 我們的包可以繼承struts-default包,繼承之後會繼承父包的所有特性
namesapce:區分不同的包的訪問路徑 eg:/base
訪問時加上/base

action標籤:動作類(依靠動作類)
name :動作類的名稱,主要用於訪問動作類的路徑
calss:動作類的限定名稱 對映對應的Class,用於Struts找到動作類
預設值:ActionSupport
method:動作類的執行方法,執行Action中的方法,預設值execute方法
result標籤:

name 用於動作類方法的返回值進行匹配
預設值:success
type:檢視的型別:如何跳轉,(轉發,重定向) 預設值,dispatcher(轉發)—redirect
/success.jsp

Struts2常量檔案修改:
default.properties:是常量檔案,定義了struts2一些常量檔案:

struts.action.extension=action,,
這個是struts2的訪問字尾名 :可以是.do .action 或者不寫

修改這個常量值,在default.properties是無法修改的,因為隸屬於jar包下的內容,

可以修改的地方:struts.xml和web.xml:
struts.xml:

<constant name="struts.action.extension" value="do,,">

web.xml:
這裡寫圖片描述

Action動作類的三種寫法:
不實現介面和繼承類:

實現Action介面
1)提供預設的execute方法,讓Action更加標準
2)提供了五個開發中常用的檢視常量:SUCCESS

必須實現Action中的execute方法
execute是struts的預設方法

繼承ActionSupport

ActionSupport實際上實現了Action介面(Struts2內部類)

1)有了Action介面的好處
2)例如表單驗證、國際化等功能
這裡寫圖片描述

實際開發中推薦使用ActionSupport

Action類的訪問三種方式:

1)傳統的訪問方式
這裡寫圖片描述

這裡寫圖片描述

配置繁瑣
可讀性很強

2)萬用字元的訪問方式

這裡寫圖片描述

要求使用者的訪問路徑必須清楚
可能有些方法名稱會衝突,所以修改方法名

可讀性差一點
配置簡單

3)動態的方法呼叫方式(瞭解)
在生產上不推薦使用,但是在struts2測試可以使用

!:感嘆號後面跟方法
這裡寫圖片描述

動態方法呼叫預設是關閉的,如果需要使用的時候需要在常量中開啟即可

這裡寫圖片描述

開啟動態方式呼叫:
這裡寫圖片描述

<constant name="struts.enable.DynamicMethodInvocation" value="true">

為什麼Struts2是預設關閉的!開啟這種方法是非常危險的,這個類中所有方法都可能被訪問到,不建議使用測試可用

  • Struts2攔截器和請求資料封裝
    result標籤中的type=“”

這裡寫圖片描述

試圖型別主要是指定struts2採用什麼樣的方式進行跳轉

dispatcher:轉發到頁面(位址列不變,是在服務端進行的)
redirect:重定向到頁面(位址列會發生改變)
redirectAction:重定向到Action

這裡寫圖片描述

檔案下載用 stream型別

全域性檢視和區域性檢視

對於方法的許可權的攔截
判斷使用者是否已經登陸

這裡寫圖片描述

這裡寫圖片描述

一個Action可以配置多個result ,這樣是區域性的,在action內部
這樣的話login.jspde的reslut有些重複,所以可以抽取出來
全域性檢視的配置:配置在package內,action外部

這裡寫圖片描述

全域性檢視特點:對當前包下的所有Action都是有效的
區域性檢視特點:只有對當前Action有效

注意事項:
區域性檢視的優先順序會大於全域性檢視的優先性
如果在區域性檢視和全域性檢視都出現相同的檢視,那麼區域性檢視的優先順序會大於全域性檢視的優先順序(也就是所謂的覆蓋)

Struts2中使用Servlet的API:
需求:從接受引數到把資料共享到頁面 都需要通過Servlet,利用ServletAPI

這裡寫圖片描述

1.使用ServletActionContext類

寫入表單:姓名、性別、年齡

HttpServletRequest request = ServletActionContext.getRequest();

這裡寫圖片描述

這裡寫圖片描述

Struts對post提交做了處理 預設編碼UTF-8

2.使用Struts2提供的ActionContext類
利用ActionContext

execute中方法:

ActionContext context = ActionContext.getParameters();
HttpParameters parameters = context.getParameters();

這裡寫圖片描述

3.使用介面注入的方式
Action繼承ActionSupport 並且實現了ServletRequestAware介面

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

實際開發中前面兩個比較推薦使用
第三個侵入性比較高,需要實現介面和寫大量程式碼

ServletActionContext實現原理:
這裡寫圖片描述
底層呼叫的是ActionContext的方法,與ActionContext 本質是一樣的

而第三種實現介面注入的方式 是由於struts2中的struts-default.xml檔案中配置的攔截器實現的

這裡寫圖片描述

ServeltConfigInterceptor攔截器
這裡寫圖片描述

通過不同的Aware來實現注入

  • 攔截器的作用與實現
    攔截器:在AOP中用於在某個方法或欄位被訪問之前,進行攔截然後在之前或之後加入一些操作,攔截是AOP的一中實現策略

攔截器 是動態攔截Action呼叫的物件,它提供了一種機制可以使開發這可以定義在一個action執行前後執行的程式碼,也可以在一個Action執行前阻止其執行,同時也提供了一種可以提取Action中可重用部分的方式(比如登陸判斷,日誌記錄)

攔截器的開發步驟:
編寫一個Action
1.編寫攔截器類
需要實現一個介面:Interceptor
這裡寫圖片描述
核心方法:intercept 方法,執行Action invoke()方法,可以在之前之後做一些操作

2.配置攔截器
在struts.xml檔案中配置
1)定義攔截器
2)使用攔截器
這裡寫圖片描述

全域性攔截器和區域性攔截器
以上就是區域性攔截器,只對配置了攔截器的某一部分Action生效,其它無效

全域性攔截器的配置:

<default-interceptor-ref name="MyInterceptor1">

這裡寫圖片描述

全域性攔截器,位置放在 定義攔截器的下方

  • *攔截器棧和預設攔截器棧
    攔截器棧:一個攔截器棧可以包含多個攔截器,
    可以使用攔截器棧哎攔截Action,多個攔截器同時施加到同一個Action

定義攔截器棧:

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

攔截器棧執行過程:

這裡寫圖片描述

在實際開發中,定義攔截器棧比較多
struts-default.xml中定義了許多的攔截器以及許多的攔截器棧

預設攔截器棧

這裡寫圖片描述

這裡寫圖片描述

根據繼承原則,所有的package都會繼承預設配置檔案的攔截器棧的內容

如果我們的包沒有去自定義攔截器,那麼會自動使用defaultStack,但是如果我們定義了攔截器,那麼我們的預設棧會被覆蓋,失效,比如自定義攔截器站,servletConfig也失效了

比如servletConfig攔截器就是屬於預設的攔截器棧中的攔截器

這時就需要我們新增defaultStack

這裡寫圖片描述

如果自定義攔截器,那麼要手動加上預設的defaultStack

  • 請求引數的封裝
    需求:以使用者註冊為例:

屬性驅動封裝
底層依靠攔截器實現:
這裡寫圖片描述

普通屬性的驅動
頁面+action
利用action中的set方法
這裡寫圖片描述

注意:表單上送欄位和set方法中的欄位必須一致

javaBean的驅動:

在Action中定義一個User物件 ,user物件的set和get方法,User類中的屬性必須和表單一致,且有set、get方法,實現序列化介面Serializable

頁面上:
這裡寫圖片描述

這裡寫圖片描述

模型驅動封裝

這裡寫圖片描述

模型驅動和屬性驅動本質採用的攔截器不同,採用的方式也不同:
這裡寫圖片描述

Action需要實現ModelDriven介面(需要泛型)User
寫法比較簡單,直接將物件屬性封裝為物件:

這裡寫圖片描述

模型驅動不需要set、get方法,必須new物件
private User user = new User();

  • Struts2國際化功能
    需求:做一個國際化的登陸頁面(i18n)

1.編寫國際化的資原始檔
2.新建message_zh_CN.properties

這裡寫圖片描述

message_en_US.properties
這裡寫圖片描述

載入國際化資原始檔:靠常量檔案載入

這裡寫圖片描述

在struts.xml中配置:
這裡寫圖片描述

struts2一啟動就會載入國際化配置資訊
字首必須是message 後邊不用寫
這裡寫圖片描述

在jsp頁面使用國際化資源資訊

引入標籤(Struts2標籤)
這裡寫圖片描述

將jsp頁面的元素換為properties檔案中的key值

這裡寫圖片描述

更改瀏覽器語言讀取不同的國際化資源
在Action也可以使用國際資源化資訊

這裡寫圖片描述

  • Strust2的型別轉換機制以及自定義轉換器
    Struts2在我們請求引數的封裝之前,其實自動會對引數進行型別轉換
    比如前端傳入年齡,成績等,後臺需要用對應的資料型別進行轉換,Struts2可以完成自動轉換

這裡寫圖片描述

這裡寫圖片描述

Struts2內部擁有型別轉換的功能

但是Struts2對於日期型別,只支援yyyy-MM-DD的格式,如果是其他格式,Struts2是不支援的,比如yyyy/MM/DD,這個時候可以自定義型別轉換器

自定義型別轉換器:
編寫自定義型別轉換器

繼承StrutsTypeConverter類,並且實現convertFromString(頁面到Action),convertToString(Action到頁面)

這裡寫圖片描述

重寫convertFromString

這裡寫圖片描述

配置型別轉換器:
在動作類的目錄下建立一個檔案Demo1Action-conversion.properties檔案,內容這裡寫圖片描述

中間必須以橫崗-分隔