1. JavaEE軟件三層結構和MVC的區別?
MVC是一種思想,是一種模式,將軟件分為 Model模型、View視圖、Controller控制器。【JavaEE開發更強調三層結構,web層開發更注重MVC】
Struts2 就是web層開發框架,符合MVC模式;struts1 、webwork 、jsf 、SpringMVC 都是MVC
2. Struts和struts2的區別有哪些?
Action類
Struts 1要求Action類要擴展自一個抽象基類。Struts 1的一個共有的問題是面向抽象類編程而不是面向接口編程。
Struts 2的Action類實現了一個Action接口,連同其他接口一起實現可選擇和自定義的服務。Struts 2提供一個名叫ActionSupport的基類實現一般使用的接口。雖然,Action接口不是必須的。任何使用execute方法的POJO對象可以 被當作Struts 2的Action對象使用。
程模型
Struts 1 Action類是單例類,因只有一個示例控制所有的請求。單例類策略造成了一定的限制且給開發帶來了額外的煩惱。Action資源必須是程安全或者同步 的。
Struts 2 Action對象每一個請求都實例化對象,所以沒有程安全的問題。(實踐中,servlet容器生許多丟的對象對於每一個請求,多於一個的對象並不影響垃 圾收集)
Servlet 依賴
Struts 1的Action類依賴於servlet API以HttpServletRequest和HttpServletResponse作參數傳給execute方法當Action被調用時。
Struts 2的Action不和容器有關。Servlet上下文被表現簡單的Maps,允許Action被獨立的測試。Struts 2的Action可以訪問最初的請求和相應,如果需要的話。然而,其他的架構元素少或者排除直接訪問HttpServletRequest或者 HttpServletResponse的需要。
易測性
測試Struts 1的主要障礙是execute方法暴露了Servlet API。第三方的擴展,Struts測試用例,提供Struts 1的集合對象。
Struts 2的Action可以通過實例化Action測試,設置屬性,然后調用方法。依賴注入的支持也是測試變得更簡單。
接受輸入
Struts 1使用ActionForm對象捕獲輸入。象Action一樣,所有的ActionForm必須擴展基類。因其他的JavaBean不能作 ActionForm使用,開發者經常創建多余的類捕獲輸入。DynaBeans可以被用來作替代ActionForm的類創建。但是開發者可以重新描述 已經存在的JavaBean。
Struts 2 Action屬性作輸入屬性,排除第二個輸入對象的需要。輸入屬性可能有豐富的對象類型這些類型有他們自己的屬性。Action的屬性可以通過標簽庫訪 問。Struts 2也支持ActionForm形式。豐富的對象類型,包含業務或者域對象,可以被當作輸入或者輸出對象使用。饃型驅動特性簡化標簽對POJO輸入對象的引 用。
表達式語言
Struts 1整和JSTL,所以它使用JSTL的表達式語言。表達式語言有基本的圖形對象移動,但是相對很弱的集合和被索引的屬性支持。
Struts 2使用JSTL,但是框架也支持更大和更靈活的表達式,叫做“對象圖形符號語言”(OGNL)。
將值綁定要視圖上
Struts 1使用標准JSP機制來綁定對象到頁面上下文。
Struts 2使用“ValueStack”技術了標簽庫可以不用鏈接你的視圖到對象的表現類型訪問值。ValueStack策略允許重用視圖。
類型轉換
Struts 1的ActionForm屬性經常都是String的。Struts 1使用Commons-Beanutils類型轉換。轉換每一個類,不是每一個實例配置。
Struts 2使用OGNL類型轉換。框架包含轉換器基本的和共同的對象類型和原始類型。
驗證
Struts 1支持手動驗證憑借ActionForm的validate方法,或者通過擴展的公用驗證器。類可以有不同的驗證上下文未相同的類,但是不能不能包括驗證 子對象。
Struts 2支持手動驗證憑借validate方法和XWork驗證框架。Xwork驗證框架支持一連串的驗證子屬性使用的驗證了屬性類的類型和嚴正上下文而定義。
Action執行的控制
Struts 1支持獨立的請求處理器對於每一個模型,但是所有在模型中的Action必須共享同一個生命周期。
Struts 2支持在每一個Action基礎上憑借攔截棧創建不同的生命周期。自定義棧可以被創建且使用不同的所需 的Action。
3. 簡要說說Struts2的處理流程?
1、加載類(FilterDispatcher)
2、讀取配置(struts配置文件中的Action)
3、派發請求(客戶端發送請求)
4、調用Action(FilterDispatcher從struts配置文件中讀取與之相對應的Action )
5、啟用攔截器(WebWork攔截器鏈自動對請求應用通用功能,如驗證)
6、處理業務(回調Action的execute()方法)
7、返回響應(通過execute方法將信息返回到FilterDispatcher)
8、查找響應(FilterDispatcher根據配置查找響應的是什么信息如:SUCCESS、ERROER,將跳轉到哪個jsp頁面)
9、響應用戶(jsp--->客戶瀏覽器端顯示)
10、struts2標簽庫(相比struts1的標簽庫,struts2是大大加強了,對數據的操作功能很強大)
請求(.action)---->經過StrutsPrepareAndExecuteFilter 核心控制器---->進入到Struts2的攔截器Interceptor(實現代碼功能)----->通過action的名稱找對應的Action類----->執行Action類的execute方法----->通過execute方法中返回的字符串,在Struts.xml中找對應的結果頁面(result)【在action執行之前,執行了defaultStack攔截器棧】
* 攔截器 在 struts-default.xml定義 【它位於sruts2-core-xxx.jar目錄下】
* 執行攔截器 是 defaultStack 中引用攔截器
4、Struts2配置文件加載順序
init_DefaultProperties(); // [1]---- org/apache/struts2/default.properties
init_TraditionalXmlConfigurations(); // [2] --- struts-default.xml,struts-plugin.xml,struts.xml
init_LegacyStrutsProperties(); // [3] --- 自定義struts.properties
init_CustomConfigurationProviders(); // [5] ----- 自定義配置提供
init_FilterInitParameters() ; // [6] ----- web.xml
init_AliasStandardObjects() ; // [7] ---- Bean加載
② struts-default.xml 該文件保存在 struts2-core-2.3.7.jar (Bean 、攔截器、結果類型 )
③ struts-plugin.xml 該文件保存在 struts-Xxx-2.3.7.jar (在插件包中存在 ,配置插件信息 ) struts-config-browser-plugin-2.3.7.jar 里面有
④ struts.xml 該文件是 web應用默認的struts 配置文件 (實際開發中,通常寫 struts.xml )
⑤ struts.properties 該文件是 Struts的默認配置文件 (配置常量 )
⑥ web.xml 該文件是 Web應用的配置文件 (配置常量 )
后加載配置文件中修改的常量的值會覆蓋前面配置文件修改的常量的值!
5、我們在書寫Action的時候有哪幾種方式?他們有什么區別?
obj =Class.forName("完整類名").newInstance();
Method m =Class.forName("完整類名").getMethod("execute");
m.invoke(obj);//通過反射 執行execute()方法
Action接口中,定義默認五種邏輯視圖名稱
// 數據處理成功 (成功頁面)
publicstatic final String SUCCESS ="success";
// 頁面不跳轉 return null; 效果一樣
publicstatic final String NONE ="none";
// 數據處理發送錯誤 (錯誤頁面)
publicstatic final String ERROR ="error";
// 用戶輸入數據有誤,通常用於表單數據校驗 (輸入頁面)
publicstatic final String INPUT ="input";
// 主要權限認證 (登陸頁面)
publicstatic final String LOGIN ="login";
代理模式,控制目標對象訪問
/hello.action 請求時StrutsPrepareAndExecuteFilter的 doFilter一定執行
//判斷配置文件中有沒有對應Action
ActionMapping mapping = prepare.findActionMapping(request, response,true);
//根據配置創建代理對象
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext,true,false);
執行時:先執行interceptor的intercept攔截方法,最后指向action的execute
6、Action是如何接受請求參數的?
<interceptor name="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
用戶名:<inputtype="text"name="username"/><br/>
publicclassRegistAction1extendsActionSupport{
privateString username;
publicvoid setUsername(String username){
this.username = username;
}
}
<!--基於OGNL表達式的寫法-->
用戶名:<inputtype="text"name="user.username"/><br/>
密 碼:
<inputtype="password"name="user.password"/><br/>
publicclassUser{
privateString username;
privateString password;
publicString getUsername(){
return username;
}
publicvoid setUsername(String username){
this.username = username;
}
publicString getPassword(){
return password;
}
publicvoid setPassword(String password){
this.password = password;
}
}
publicclassRegistAction2extendsActionSupport{
privateUser user;
publicvoid setUser(User user){
this.user = user;
}
//必須提供get方法(封裝第一個參數時,創建新的User對象, 封裝第二個參數需要使用第一個創建user對象)
publicUser getUser(){
return user;
}
}
<interceptorname="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>
<interceptorname="modelDriven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/> 為模型驅動提供了更多特性
用戶名:<inputtype="text"name="username"/><br/>
publicclassRegistAction3extendsActionSupportimplementsModelDriven<User>{
// 模型對象必須手動實例化
privateUser user =newUser();
publicUser getModel(){
return user;
}
}
<inputtype="text"name="user.username"/>
<inputtype="text"name="product.info"/>
7、Action的相關配置?
配置package 三個常用屬性
<packagename="default"namespace="/"extends="struts-default">
②namespace和 <action>的name屬性,決定 Action的訪問路徑 (以/開始 )
namespace="/" :根名稱空間
namespace="/aa/" :帶有名稱空間的路徑
③extends繼承哪個包,通常開發中繼承struts-default包 (struts-default包在 struts-default.xml中定義 )【可以使用包中默認的攔截器和結果集】
2)Action是通過<action>元素配置
<action name="hello"class="cn.itcast.struts2.demo1.HelloAction" method="execute">
例如:
<package name="default"namespace="/user" extends="struts-default">
<action name="hello"class="cn.itcast.struts2.demo1.HelloAction">
<result name="success">/demo1/success.jsp</result>
</action>
</package>
3) <action> 元素配置默認值
<action> 的class 默認值 ActionSupport 類 <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
<result> 的 name 默認值 success
8、Action訪問Servlet API有哪幾種方式,簡單的介紹一下
9. 說說Struts2的輸入校驗流程
A:類型轉換器負責對字符串的請求參數執行類型轉換,並將這些值設置成Action的屬性值B:在執行類型轉換過程中可能出現異常,如果出現異常,將異常信息保存到ActionContext中,convertionError攔截器將負責將其封裝到fieldError里,如果沒有異常,直接進入第3步C:調用Struts2的內置校驗規則進行輸入校驗D:通過反射調用validateXXX()方法E:調用Action類中的validate()方法F:如果上面的幾步中沒有出FiledError,就調用Acton中的邏輯處理方法,如果有,則進入input視圖
10. Struts2 form標簽數據為什么可以回顯?
11. 什么是值棧?值棧的內部結構?
ContextMap: Struts 把各種各樣的映射關系(一些 Map 類型的對象) 壓入ContextMap 中, Struts 會把下面這些映射壓入 ContextMap 中
parameters: 該 Map 中包含當前請求的請求參數request: 該 Map 中包含當前 request 對象中的所有屬性session: 該 Map 中包含當前 session 對象中的所有屬性application:該 Map 中包含當前 application 對象中的所有屬性attr: 該 Map 按如下順序來檢索某個屬性: request, session, application
* CompoundRoot 就是ArrayList
* OgnlContext 就是 Map
* context中還存在 request、 session、application、 attr、 parameters 對象引用
* OGNL表達式,訪問root中數據時 不需要 #, 訪問 request、 session、application、 attr、 parameters 對象數據 必須寫 #
* 操作值棧 默認指 操作 root 元素
12. 值棧對象的創建 ,ValueStack 和 ActionContext 是什么關系 ?
13.如何獲得值棧對象?
14.如何向值棧中保存數據?如何在jsp頁面中獲取值棧的數據?
<s:property value="[0].top"/> //取值棧頂對象
valueStack:<s:property value="username"/>
request:<s:property value="#request.username"/>session:<s:property value="#session.username"/>application:<s:property value="#application.username"/>attr:<s:property value="#attr.username"/>parameters:<s:property value="#parameters.cid[0]"/>
15.為什么EL也能訪問值棧中的數據?
* 對Request對象進行了包裝 ,StrutsRequestWrapper* 重寫request的 getAttribute
16.你在開發中,值棧主要有哪些應用?
this.addFieldError("msg", "字段錯誤信息");this.addActionError("Action全局錯誤信息");this.addActionMessage("Action的消息信息");
<s:fielderror fieldName="msg"/><s:actionerror/><s:actionmessage/>