技術(shù)分析之在Struts2框架中使用Servlet的API
1. 在Action類中也可以獲取到Servlet一些常用的API
需求:提供JSP的表單頁面的數(shù)據(jù),在Action中使用Servlet的API接收到,然后保存到三個域?qū)ο笾?,最后再顯示到JSP的頁面上。
提供JSP注冊的頁面,演示下面這三種方式
1
2
3
4
5
6
|
< h3 >注冊頁面</ h3 > < form action = "${ pageContext.request.contextPath }/xxx.action" method = "post" > 姓名:< input type = "text" name = "username" />< br /> 密碼:< input type = "password" name = "password" />< br /> < input type = "submit" value = "注冊" /> </ form > |
2. 完全解耦合的方式
如果使用該種方式,Struts2框架中提供了一個類,ActionContext類,該類中提供一些方法,通過方法獲取Servlet的API
一些常用的方法如下
- static ActionContext getContext() -- 獲取ActionContext對象實例
- java.util.Map<java.lang.String,java.lang.Object> getParameters() -- 獲取請求參數(shù),相當(dāng)于request.getParameterMap();
- java.util.Map<java.lang.String,java.lang.Object> getSession() -- 獲取的代表session域的Map集合,就相當(dāng)于操作session域。
- java.util.Map<java.lang.String,java.lang.Object> getApplication() -- 獲取代表application域的Map集合
- void put(java.lang.String key, java.lang.Object value) -- 注意:向request域中存入值。
3. 使用原生Servlet的API的方式(常用到)
Struts2框架提供了一個類,ServletActionContext,該類中提供了一些靜態(tài)的方法
具體的方法如下
- getPageContext()
- getRequest()
- getResponse()
- getServletContext()
技術(shù)分析之結(jié)果頁面的跳轉(zhuǎn)
1. 結(jié)果頁面存在兩種方式
全局結(jié)果頁面
> 條件:如果<package>包中的一些action都返回success,并且返回的頁面都是同一個JSP頁面,這樣就可以配置全局的結(jié)果頁面。
> 全局結(jié)果頁面針對的當(dāng)前的包中的所有的Action,但是如果局部還有結(jié)果頁面,會優(yōu)先局部的。使用的標簽是
1
2
3
|
< global-results > < result >/demo3/suc.jsp</ result > </ global-results > |
局部結(jié)果頁面
1
|
< result >/demo3/suc.jsp</ result > |
2. 結(jié)果頁面的類型
結(jié)果頁面使用<result>標簽進行配置,包含兩個屬性
> name -- 邏輯視圖的名稱
> type -- 跳轉(zhuǎn)的類型,值一些,需要掌握一些常用的類型。常見的結(jié)果類型去struts-default.xml中查找。
- dispatcher -- 轉(zhuǎn)發(fā).type的默認值.Action--->JSP
- redirect -- 重定向. Action--->JSP
- chain -- 多個action之間跳轉(zhuǎn).從一個Action轉(zhuǎn)發(fā)到另一個Action. Action---Action
- redirectAction -- 多個action之間跳轉(zhuǎn).從一個Action重定向到另一個Action. Action---Action
- stream -- 文件下載時候使用的
技術(shù)分析之Struts2框架的數(shù)據(jù)封裝
1. 為什么要使用數(shù)據(jù)的封裝呢?
- 作為MVC框架,必須要負責(zé)解析HTTP請求參數(shù),并將其封裝到Model對象中
- 封裝數(shù)據(jù)為開發(fā)提供了很多方便
- Struts2框架提供了很強大的數(shù)據(jù)封裝的功能,不再需要使用Servlet的API完成手動封裝了!!
2. Struts2中提供了兩類數(shù)據(jù)封裝的方式?
第一種方式:屬性驅(qū)動
> 提供對應(yīng)屬性的set方法進行數(shù)據(jù)的封裝。
表單的哪些屬性需要封裝數(shù)據(jù),那么在對應(yīng)的Action類中提供該屬性的set方法即可。
表單中的數(shù)據(jù)提交,最終找到Action類中的setXxx的方法,最后賦值給全局變量。
注意0:Struts2的框架采用的攔截器完成數(shù)據(jù)的封裝。
注意1:這種方式不是特別好:因為屬性特別多,提供特別多的set方法,而且還需要手動將數(shù)據(jù)存入到對象中.
注意2:這種情況下,Action類就相當(dāng)于一個JavaBean,就沒有體現(xiàn)出MVC的思想,Action類又封裝數(shù)據(jù),又接收請求處理,耦合性較高。
> 在頁面上,使用OGNL表達式進行數(shù)據(jù)封裝。
在頁面中使用OGNL表達式進行數(shù)據(jù)的封裝,就可以直接把屬性封裝到某一個JavaBean的對象中。
在頁面中定義一個JavaBean,并且提供set方法:例如:private User user;
頁面中的編寫發(fā)生了變化,需要使用OGNL的方式,表單中的寫法:<input type="text" name="user.username">
注意:只提供一個set方法還不夠,必須還需要提供user屬性的get和set方法!??!
> 先調(diào)用get方法,判斷一下是否有user對象的實例對象,如果沒有,調(diào)用set方法把攔截器創(chuàng)建的對象注入進來,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
/** 屬性驅(qū)動方式,把數(shù)據(jù)封裝到JavaBean的對象中 @author Administrator */ public class Regist2Action extends ActionSupport{ private static final long serialVersionUID = 6556880331550390473L; // 注意二:屬性驅(qū)動的方式,現(xiàn)在,要提供是get和set方法 private User user; public User getUser() { System.out.println( "getUser..." ); return user; } public void setUser(User user) { System.out.println( "setUser..." ); this .user = user; } public String execute() throws Exception { System.out.println(user); return NONE; } } |
第二種方式:模型驅(qū)動
> 使用模型驅(qū)動的方式,也可以把表單中的數(shù)據(jù)直接封裝到一個JavaBean的對象中,并且表單的寫法和之前的寫法沒有區(qū)別!
> 編寫的頁面不需要任何變化,正常編寫name屬性的值
> 模型驅(qū)動的編寫步驟:
手動實例化JavaBean,即:private User user = new User();
必須實現(xiàn)ModelDriven<T>接口,實現(xiàn)getModel()的方法,在getModel()方法中返回user即可!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/** 模型驅(qū)動的方式 實現(xiàn)ModelDriven接口 必須要手動實例化對象(需要自己new好) @author Administrator */ public class Regist3Action extends ActionSupport implements ModelDriven<User>{ private static final long serialVersionUID = 6556880331550390473L; // 必須要手動實例化 private User user = new User(); // 獲取模型對象 public User getModel() { return user; } public String execute() throws Exception { System.out.println(user); return NONE; } } |
技術(shù)分析之Struts2把數(shù)據(jù)封裝到集合中
1. 封裝復(fù)雜類型的參數(shù)(集合類型 Collection 、Map接口等)
2. 需求:頁面中有可能想批量添加一些數(shù)據(jù),那么現(xiàn)在就可以使用上述的技術(shù)了。把數(shù)據(jù)封裝到集合中
3. 把數(shù)據(jù)封裝到Collection中
因為Collection接口都會有下標值,所有頁面的寫法會有一些區(qū)別,注意:
1
|
< input type = "text" name = "products[0].name" /> |
在Action中的寫法,需要提供products的集合,并且提供get和set方法。
4. 把數(shù)據(jù)封裝到Map中
Map集合是鍵值對的形式,頁面的寫法
1
|
< input type = "text" name = "map['one'].name" /> |
Action中提供map集合,并且提供get和set方法
代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
/** 屬性驅(qū)動的方式,把數(shù)據(jù)封裝到map集合中 @author Administrator */ public class Regist5Action extends ActionSupport{ private static final long serialVersionUID = 6556880331550390473L; private Map<String, User> map; public Map<String, User> getMap() { return map; } public void setMap(Map<String, User> map) { this .map = map; } public String execute() throws Exception { System.out.println(map); return NONE; } } |
案例總結(jié)之Struts2的攔截器技術(shù)
1. 攔截器的概述
攔截器就是AOP(Aspect-Oriented Programming)的一種實現(xiàn)。(AOP是指用于在某個方法或字段被訪問之前,進行攔截然后在之前或之后加入某些操作。)
過濾器:過濾從客服端發(fā)送到服務(wù)器端請求的
攔截器:攔截對目標Action中的某些方法進行攔截
- 攔截器不能攔截JSP
- 攔截到Action中某些方法
2. 攔截器和過濾器的區(qū)別
1)攔截器是基于JAVA反射機制的,而過濾器是基于函數(shù)回調(diào)的
2)過濾器依賴于Servlet容器,而攔截器不依賴于Servlet容器
3)攔截器只能對Action請求起作用(Action中的方法),而過濾器可以對幾乎所有的請求起作用(CSS JSP JS)
攔截器 采用 責(zé)任鏈 模式
> 在責(zé)任鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈
> 責(zé)任鏈每一個節(jié)點,都可以繼續(xù)調(diào)用下一個節(jié)點,也可以阻止流程繼續(xù)執(zhí)行
在struts2 中可以定義很多個攔截器,將多個攔截器按照特定順序 組成攔截器棧 (順序調(diào)用 棧中的每一個攔截器 )
3. Struts2的核心是攔截器,看一下Struts2的運行流程
自定義攔截器和配置
1. 編寫攔截器,需要實現(xiàn)Interceptor接口,實現(xiàn)接口中的三個方法
1
2
3
4
5
6
7
8
9
|
protected String doIntercept(ActionInvocation invocation) throws Exception { // 獲取session對象 User user = (User) ServletActionContext.getRequest().getSession().getAttribute( "existUser" ); if (user == null ){ // 說明,沒有登錄,后面就不會執(zhí)行了 return "login" ; } return invocation.invoke(); } |
2. 需要在struts.xml中進行攔截器的配置,配置一共有兩種方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
<!-- 定義了攔截器 第一種方式 <interceptors> <interceptor name="DemoInterceptor" class="com.itheima.interceptor.DemoInterceptor"/> </interceptors> --> <!-- 第二種方式:定義攔截器棧 --> < interceptors > < interceptor name = "DemoInterceptor" class = "com.itheima.interceptor.DemoInterceptor" /> <!-- 定義攔截器棧 --> < interceptor-stack name = "myStack" > < interceptor-ref name = "DemoInterceptor" /> < interceptor-ref name = "defaultStack" /> </ interceptor-stack > </ interceptors > < action name = "userAction" class = "com.itheima.demo3.UserAction" > <!-- 只要是引用自己的攔截器,默認棧的攔截器就不執(zhí)行了,必須要手動引入默認棧 <interceptor-ref name="DemoInterceptor"/> <interceptor-ref name="defaultStack"/> --> <!-- 引入攔截器棧就OK --> < interceptor-ref name = "myStack" /> </ action > |
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://www.cnblogs.com/lxp503238/p/6825469.html?utm_source=tuicool&utm_medium=referral