Struts2面試題
1、struts2工作流程
Struts 2框架本身大致可以分為3個部分:
核心控制器FilterDispatcher、業務控制器Action和使用者實現的企業業務邏輯元件。
核心控制器FilterDispatcher是Struts 2框架的基礎,
包含了框架內部的控制流程和處理機制。
業務控制器Action和業務邏輯元件是需要使用者來自己實現的。
使用者在開發Action和業務邏輯元件的同時,還需要編寫相關的配置檔案,
供核心控制器FilterDispatcher來使用。
Struts 2的工作流程相對於Struts 1要簡單,與WebWork框架基本相同,
所以說Struts 2是WebWork的升級版本。基本簡要流程如下:
1 、客戶端初始化一個指向Servlet容器的請求;
2、 這個請求經過一系列的過濾器(Filter)
(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,
這個過濾器對於Struts2和其他框架的整合很有幫助,例如:SiteMesh Plugin)
3 、接著FilterDispatcher被呼叫,
FilterDispatcher詢問ActionMapper來決定這個請是否需要呼叫某個Action
4、如果ActionMapper決定需要呼叫某個Action,
FilterDispatcher把請求的處理交給ActionProxy
5、ActionProxy通過Configuration Manager詢問框架的配置檔案,
找到需要呼叫的Action類
6、ActionProxy建立一個ActionInvocation的例項。
7、ActionInvocation例項使用命名模式來呼叫,
在呼叫Action的過程前後,涉及到相關攔截器(Intercepter)的呼叫。
8、一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果 。返回結果通常是(但不總是,也可 能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。 在表示的過程中可以使用Struts2 框架中繼承的標籤。 在這個過程中需要涉及到ActionMapper
9、響應的返回是通過我們在web.xml中配置的過濾器
10、如果ActionContextCleanUp是當前使用的,則FilterDispatecher將不會清理sreadlocal ActionContext;如果ActionContextCleanUp不使用,則將會去清理sreadlocals。
2、說下Struts的設計模式
MVC模式: web應用程式啟動時就會載入並初始化ActionServler。使用者提交表單時,一個配置好的ActionForm物件被建立,並被填入表單相應的資料,ActionServler根據Struts-config.xml檔案配置好的設定決定是否需要表單驗證,如果需要就呼叫ActionForm的Validate()驗證後選擇將請求傳送到哪個Action,如果Action不存在,ActionServlet會先建立這個物件,然後呼叫Action的execute()方法。Execute()從ActionForm物件中獲取資料,完成業務邏輯,返回一個ActionForward物件,ActionServlet再把客戶請求轉發給ActionForward物件指定的jsp元件,ActionForward物件指定的jsp生
成動態的網頁,返回給客戶。
3、攔截器和過濾器的區別
1、攔截器是基於java反射機制的,而過濾器是基於函式回撥的。
2、過濾器依賴於servlet容器,而攔截器不依賴於servlet容器。
3、攔截器只能對Action請求起作用,而過濾器則可以對幾乎所有請求起作用。
4、攔截器可以訪問Action上下文、值棧裡的物件,而過濾器不能。
5、在Action的生命週期中,攔截器可以多次呼叫,而過濾器只能在容器初始化時被呼叫一次。
4、struts1於struts2的比較
1、Action 類:
Struts1要求Action類繼承一個抽象基類。Struts1的一個普遍問題是使用抽象類程式設計而不是介面。
Struts 2 Action類可以實現一個Action介面,也可實現其他介面,使可選和定製的服務成為可能。Struts2提供一個ActionSupport基類去 實現常用的介面。Action介面不是必須的,任何有execute標識的POJO物件都可以用作Struts2的Action物件。
2、執行緒模式:
Struts1 Action是單例模式並且必須是執行緒安全的,因為僅有Action的一個例項來處理所有的請求。單例策略限制了Struts1 Action能作的事,並且要在開發時特別小心。Action資源必須是執行緒安全的或同步的。
Struts2 Action物件為每一個請求產生一個例項,因此沒有執行緒安全問題。(實際上,servlet容器給每個請求產生許多可丟棄的物件,並且不會導致效能和垃圾回收問題)
3、Servlet 依賴:
Struts1 Action 依賴於Servlet API ,因為當一個Action被呼叫時HttpServletRequest 和 HttpServletResponse 被傳遞給execute方法。
Struts 2 Action不依賴於容器,允許Action脫離容器單獨被測試。如果需要,Struts2 Action仍然可以訪問初始的request和response。但是,其他的元素減少或者消除了直接訪問HttpServetRequest 和 HttpServletResponse的必要性。
4、可測性:
測試Struts1 Action的一個主要問題是execute方法暴露了servlet API(這使得測試要依賴於容器)。一個第三方擴充套件--Struts TestCase--提供了一套Struts1的模擬物件(來進行測試)。
Struts 2 Action可以通過初始化、設定屬性、呼叫方法來測試,“依賴注入”支援也使測試更容易。
5、捕獲輸入:
Struts1 使用ActionForm物件捕獲輸入。所有的ActionForm必須繼承一個基類。因為其他JavaBean不能用作ActionForm,開發者經 常建立多餘的類捕獲輸入。動態Bean(DynaBeans)可以作為建立傳統ActionForm的選擇,但是,開發者可能是在重新描述(建立)已經存 在的JavaBean(仍然會導致有冗餘的javabean)。
Struts 2直接使用Action屬性作為輸入屬性,消除了對第二個輸入物件的需求。輸入屬性可能是有自己(子)屬性的rich物件型別。Action屬效能夠通過 web頁面上的taglibs訪問。Struts2也支援ActionForm模式。rich物件型別,包括業務物件,能夠用作輸入/輸出物件。這種 ModelDriven 特性簡化了taglib對POJO輸入物件的引用。
6、表示式語言:
Struts1 整合了JSTL,因此使用JSTL EL。這種EL有基本物件圖遍歷,但是對集合和索引屬性的支援很弱。
Struts2可以使用JSTL,但是也支援一個更強大和靈活的表示式語言-- "Object Graph Notation Language " (OGNL).
7、繫結值到頁面(view):
Struts 1使用標準JSP機制把物件繫結到頁面中來訪問。
Struts 2 使用 "ValueStack "技術,使taglib能夠訪問值而不需要把你的頁面(view)和物件繫結起來。ValueStack策略允許通過一系列名稱相同但型別不同的屬性重用頁面(view)。
8、型別轉換:
Struts 1 ActionForm 屬性通常都是String型別。Struts1使用Commons-Beanutils進行型別轉換。每個類一個轉換器,對每一個例項來說是不可配置的。
Struts2 使用OGNL進行型別轉換。提供基本和常用物件的轉換器。
9、校驗:
Struts 1支援在ActionForm的validate方法中手動校驗,或者通過Commons Validator的擴充套件來校驗。同一個類可以有不同的校驗內容,但不能校驗子物件。
Struts2支援通過validate方法和XWork校驗框架來進行校驗。XWork校驗框架使用為屬性類型別定義的校驗和內容校驗,來支援chain校驗子屬性
10、Action執行的控制:
Struts1支援每一個模組有單獨的Request Processors(生命週期),但是模組中的所有Action必須共享相同的生命週期。
Struts2支援通過攔截器堆疊(Interceptor Stacks)為每一個Action建立不同的生命週期。堆疊能夠根據需要和不同的Action一起使用。
為什麼要使用Struts2
Struts2 是一個相當強大的Java Web開源框架,是一個基於POJO的Action的MVC Web框架。它基於當年的Webwork和XWork框架,繼承其優點,同時做了相當的改進。
1.Struts2基於MVC架構,框架結構清晰,開發流程一目瞭然,開發人員可以很好的掌控開發的過程。
2使用OGNL進行引數傳遞。
OGNL提供了在Struts2裡訪問各種作用域中的資料的簡單方式,你可以方便的獲取Request,Attribute,Application,Session,Parameters中的資料。大大簡化了開發人員在獲取這些資料時的程式碼量。
3強大的攔截器
Struts2 的攔截器是一個Action級別的AOP,Struts2中的許多特性都是通過攔截器來實現的,例如異常處理,檔案上傳,驗證等。攔截器是可配置與重用的,可以將一些通用的功能如:登入驗證,許可權驗證等置於攔截器中以完成一些Java Web專案中比較通用的功能。在我實現的的一Web專案中,就是使用Struts2的攔截器來完成了系統中的許可權驗證功能。
4易於測試
Struts2的Action都是簡單的POJO,這樣可以方便的對Struts2的Action編寫測試用例,大大方便了5Java Web專案的測試。
易於擴充套件的外掛機制在Struts2新增擴充套件是一件愉快而輕鬆的事情,只需要將所需要的Jar包放到WEB-INF/lib資料夾中,在struts.xml中作一些簡單的設定就可以實現擴充套件。
6模組化管理
Struts2已經把模組化作為了體系架構中的基本思想,可以通過三種方法來將應用程式模組化:將配置資訊拆分成多個檔案把自包含的應用模組建立為外掛建立新的框架特性,即將與特定應用無關的新功能組織成外掛,以新增到多個應用中去。
7全域性結果與宣告式異常
為應用程式新增全域性的Result,和在配置檔案中對異常進行處理,這樣當處理過程中出現指定異常時,可以跳轉到特定頁面。
他的如此之多的優點,是很多人比較的青睞,與spring ,Hibernate進行結合,組成了現在比較流行的ssh框架,當然每個公司都要自己的框架,也是ssh變異的產品。
struts2有哪些優點?
1)在軟體設計上Struts2的應用可以不依賴於Servlet API和struts API。 Struts2的這種設計屬於無侵入式設計;
2)攔截器,實現如引數攔截注入等功能;
3)型別轉換器,可以把特殊的請求引數轉換成需要的型別;
4)多種表現層技術,如:JSP、freeMarker、Velocity等;
5)Struts2的輸入校驗可以對指定某個方法進行校驗;
6)提供了全域性範圍、包範圍和Action範圍的國際化資原始檔管理實現
struts2是如何啟動的?
struts2框架是通過Filter啟動的,即StrutsPrepareAndExecuteFilter,此過濾器為struts2的核心過濾器;
StrutsPrepareAndExecuteFilter的init()方法中將會讀取類路徑下預設的配置檔案struts.xml完成初始化操作。struts2讀取到struts.xml的內容後,是將內容封裝進javabean物件然後存放在記憶體中,以後使用者的每次請求處理將使用記憶體中的資料,而不是每次請求都讀取struts.xml檔案。
struts2框架的核心控制器是什麼?它有什麼作用?
1)Struts2框架的核心控制器是StrutsPrepareAndExecuteFilter。
2)作用:
負責攔截由<url-pattern>/*</url-pattern>指定的所有使用者請求,當用戶請求到達時,該Filter會過濾使用者的請求。預設情況下,如果使用者請求的路徑
不帶字尾或者字尾以.action結尾,這時請求將被轉入struts2框架處理,否則struts2框架將略過該請求的處理。
可以通過常量"struts.action.extension"修改action的字尾,如:
<constant name="struts.action.extension" value="do"/>
如果使用者需要指定多個請求字尾,則多個字尾之間以英文逗號(,)隔開。
<constant name="struts.action.extension" value="do,go"/>
struts2配置檔案的載入順序?
struts.xml ——> struts.properties
常量可以在struts.xml或struts.properties中配置,如果在多個檔案中配置了同一個常量,則後一個檔案中配置的常量值會覆蓋前面檔案中配置的常量值.
struts.xml檔案的作用:通知Struts2框架載入對應的Action資源
struts2常量的修改方式?
常量可以在struts.xml或struts.properties中配置,兩種配置方式如下:
1)在struts.xml檔案中配置常量
<constant name="struts.action.extension" value="do"/>
2)在struts.properties中配置常量(struts.properties檔案放置在src下):
struts.action.extension=do
struts2如何訪問HttpServletRequest、HttpSession、ServletContext三個域物件?
方案一:
HttpServletRequest request =ServletActionContext.getRequest();
HttpServletResponse response =ServletActionContext.getResponse();
HttpSession session= request.getSession();
ServletContext servletContext=ServletActionContext.getServletContext();
方案二:
類 implements ServletRequestAware,ServletResponseAware,SessionAware,ServletContextAware
注意:框架自動傳入對應的域物件
struts2是如何管理action的?這種管理方式有什麼好處?
struts2框架中使用包來管理Action,包的作用和java中的類包是非常類似的。
主要用於管理一組業務功能相關的action。在實際應用中,我們應該把一組業務功能相關的Action放在同一個包下。
struts2中的預設包struts-default有什麼作用?
1)struts-default包是由struts內建的,它定義了struts2內部的眾多攔截器和Result型別,而Struts2很多核心的功能都是通過這些內建的攔截器實現,如:從請求中
把請求引數封裝到action、檔案上傳和資料驗證等等都是通過攔截器實現的。當包繼承了struts-default包才能使用struts2為我們提供的這些功能。
2)struts-default包是在struts-default.xml中定義,struts-default.xml也是Struts2預設配置檔案。 Struts2每次都會自動載入 struts-default.xml檔案。
3)通常每個包都應該繼承struts-default包。
struts2如何對指定的方法進行驗證?
1)validate()方法會校驗action中所有與execute方法簽名相同的方法;
2)要校驗指定的方法通過重寫validateXxx()方法實現, validateXxx()只會校驗action中方法名為Xxx的方法。其中Xxx的第一個字母要大寫;
3)當某個資料校驗失敗時,呼叫addFieldError()方法往系統的fieldErrors新增校驗失敗資訊(為了使用addFieldError()方法,action可以繼承ActionSupport), 如果系統 的fieldErrors包含失敗資訊,struts2會將請求轉發到名為input的result;
4)在input檢視中可以通過<s:fielderror/>顯示失敗資訊。
5)先執行validateXxxx()->validate()->如果出錯了,會轉發<result name="input"/>所指定的頁面,如果不出錯,會直接進行Action::execute()方法
struts2預設能解決get和post提交方式的亂碼問題嗎?
不能。struts.i18n.encoding=UTF-8屬性值只能解析POST提交下的亂碼問題。
請你寫出struts2中至少5個的預設攔截器?
fileUpload 提供檔案上傳功能
i18n 記錄使用者選擇的locale
cookies 使用配置的name,value來是指cookies
checkbox 添加了checkbox自動處理程式碼,將沒有選中的checkbox的內容設定為false,而html預設情況下不提交沒有選中的checkbox。
chain 讓前一個Action的屬性可以被後一個Action訪問,現在和chain型別的result()結合使用。
alias 在不同請求之間將請求引數在不同名字件轉換,請求內容不變
值棧ValueStack的原理與生命週期?
1)ValueStack貫穿整個 Action 的生命週期,儲存在request域中,所以ValueStack和request的生命週期一樣。當Struts2接受一個請求時,會迅速建立ActionContext,
ValueStack,action。然後把action存放進ValueStack,所以action的例項變數可以被OGNL訪問。 請求來的時候,action、ValueStack的生命開始,請求結束,action、 ValueStack的生命結束;
2)action是多例的,和Servlet不一樣,Servelt是單例的;
3)每個action的都有一個對應的值棧,值棧存放的資料型別是該action的例項,以及該action中的例項變數,Action物件預設儲存在棧頂;
4)ValueStack本質上就是一個ArrayList;
5)關於ContextMap,Struts 會把下面這些對映壓入 ContextMap 中:
parameters : 該 Map 中包含當前請求的請求引數
request : 該 Map 中包含當前 request 物件中的所有屬性 session :該 Map 中包含當前 session 物件中的所有屬性
application :該 Map 中包含當前 application 物件中的所有屬性
attr:該 Map 按如下順序來檢索某個屬性: request, session, application
6)使用OGNL訪問值棧的內容時,不需要#號,而訪問request、session、application、attr時,需要加#號;
7)注意: Struts2中,OGNL表示式需要配合Struts標籤才可以使用。如:<s:property value="name"/>
8)在struts2配置檔案中引用ognl表示式 ,引用值棧的值 ,此時使用的"$",而不是#或者%;
ActionContext、ServletContext、pageContext的區別?
1)ActionContext是當前的Action的上下文環境,通過ActionContext可以獲取到request、session、ServletContext等與Action有關的物件的引用;
2)ServletContext是域物件,一個web應用中只有一個ServletContext,生命週期伴隨整個web應用;
3)pageContext是JSP中的最重要的一個內建物件,可以通過pageContext獲取其他域物件的應用,同時它是一個域物件,作用範圍只針對當前頁面,當前頁面結束時,pageContext銷燬,
生命週期是JSP四個域物件中最小的。
result的type屬性中有哪幾種結果型別?
一共10種:
dispatcher
struts預設的結果型別,把控制權轉發給應用程式裡的某個資源不能把控制權轉發給一個外部資源,若需要把控制權重定向到一個外部資源, 應該使用
redirect結果型別
redirect 把響應重定向到另一個資源(包括一個外部資源)
redirectAction 把響應重定向到另一個 Action
freemarker、velocity、chain、httpheader、xslt、plainText、stream
攔截器的生命週期與工作過程?
1)每個攔截器都是實現了Interceptor介面的 Java 類;
2)init(): 該方法將在攔截器被建立後立即被呼叫, 它在攔截器的生命週期內只被呼叫一次. 可以在該方法中對相關資源進行必要的初始化;
3)intercept(ActionInvocation invocation): 每攔截一個動作請求, 該方法就會被呼叫一次;
4)destroy: 該方法將在攔截器被銷燬之前被呼叫, 它在攔截器的生命週期內也只被呼叫一次;
5)struts2中有內建了18個攔截器。
struts2如何完成檔案的上傳?
1、JSP頁面:
1)JSP頁面的上傳檔案的元件:<s: file name=”upload” />,如果需要一次上傳多個檔案, 就必須使用多個 file 標籤, 但它們的名字必須是相同的,即:
name=“xxx”的值必須一樣;
2)必須把表單的enctype屬性設定為:multipart/form-data;
3)表單的方法必須為post,因為post提交的資料在訊息體中,而無大小限制。
2、對應的action:
1)在 Action 中新新增 3 個和檔案上傳相關的屬性;
2)如果是上傳單個檔案, uploadImage屬性的型別就是 java.io.File, 它代表被上傳的檔案, 第二個和第三個屬性的型別是 String, 它們分別代表上傳文
件的檔名和檔案型別,定義方式是分別是:
jsp頁面file元件的名稱+ContentType, jsp頁面file元件的名稱+FileName
3)如果上上傳多個檔案, 可以使用陣列或 List
struts的工作原理
1、初始化,讀取struts-config.xml、web.xml等配置檔案(所有配置檔案的初始化)
2、傳送HTTP請求,客戶端傳送以.do結尾的請求
3、填充FormBean(例項化、復位、填充資料、校驗、儲存)
4、將請求轉發到Action(呼叫Action的execute()方法)
5、處理業務(可以呼叫後臺類,返回ActionForward物件)
6、返回目標響應物件(從Action返回到ActionServlet)
7、轉換Http請求到目標響應物件(查詢響應,根據返回的Forward keyword)
8、Http響應,返回到Jsp頁面
用自己的話簡要闡述struts2的執行流程。
Struts 2框架本身大致可以分為3個部分:核心控制器FilterDispatcher、業務控制器Action和使用者實現的企業業務邏輯元件。
核心控制器FilterDispatcher是Struts 2框架的基礎,包含了框架內部的控制流程和處理機制。
業務控制器Action和業務邏輯元件是需要使用者來自己實現的。使用者在開發Action和業務邏輯元件的同時,還需要編寫相關的配置檔案,供核心控制器FilterDispatcher來使用。
Struts 2的工作流程相對於Struts 1要簡單,與WebWork框架基本相同,所以說Struts 2是WebWork的升級版本。基本簡要流程如下:
1、客戶端瀏覽器發出HTTP請求。
2、根據web.xml配置,該請求被FilterDispatcher接收。
3、根據struts.xml配置,找到需要呼叫的Action類和方法, 並通過IoC方式,將值注入給Aciton。
4、Action呼叫業務邏輯元件處理業務邏輯,這一步包含表單驗證。
5、Action執行完畢,根據struts.xml中的配置找到對應的返回結果result,並跳轉到相應頁面。
6、返回HTTP響應到客戶端瀏覽器。
它是以Webwork的設計思想為核心,吸收struts1的優點,可以說 struts2是struts1和Webwork結合的產物。 struts2 的工作原理圖: 一個請求在Struts2框架中的處理分為以下幾個步驟: 1.客戶端發出一個指向servlet容器的請求(tomcat); 2.這個請求會經過圖中的幾個過濾器,最後會到達FilterDispatcher過濾器。 3.過濾器FilterDispatcher是struts2框架的心臟,在處理使用者請求時,它和請求一起相互配合訪問struts2 的底層框架結構。在web容器啟動時,struts2框架會自動載入配置檔案裡相關引數,並轉換成相應的類。 如:ConfigurationManager、ActionMapper和ObjectFactory。ConfigurationManager 存有配置檔案的一 些基本資訊,ActionMapper存有action的配置資訊。在請求過程中所有的物件(Action,Results, Interceptors,等)都是通過ObjectFactory來建立的。過濾器會通過詢問ActionMapper類來查詢請求中 需要用到的Action。 4.如果找到需要呼叫的Action,過濾器會把請求的處理交給ActionProxy。ActionProxy為Action的代理物件 。ActionProxy通過ConfigurationManager詢問框架的配置檔案,找到需要呼叫的Action類。 5.ActionProxy建立一個ActionInvocation的例項。ActionInvocation在ActionProxy層之下,它表示了 Action的執行狀態,或者說它控制的Action的執行步驟。它持有Action例項和所有的Interceptor。 6.ActionInvocation例項使用命名模式來呼叫,1. ActionInvocation初始化時,根據配置,載入Action相 關的所有Interceptor。2. 通過ActionInvocation.invoke方法呼叫Action實現時,執行Interceptor。在 呼叫Action的過程前後,涉及到相關攔截器(intercepetor)的呼叫。 7. 一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果。返回結果 通常是(但不總是,也可能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。在表 示的過程中可以使用Struts2 框架中繼承的標籤。