struts2知識複習之二

## Struts2訪問Servlet

1 概述:在Struts2中,Action並沒有直接和Servlet API耦合,Action不能直接訪問Servlet API。

  儘管Action和Servlet的API的解耦會帶來很多好處,但在實現業務邏輯時,還是要經常訪問到Servlet中的對象。

2 ActionContext類:

(1)概述:Struts2提供ActionContext類來訪問Servlet API。ActionContext類是Action執行的上下文對象,保存了

   Action執行所需的所有對象,如parameters,request,session,application。

(2)ActionContext的生命週期和獲取方式

<1>生命週期

每次接收請求到Action就會創建一個相應的ActionContext對象,請求處理完自動銷燬ActionContext

<2>獲取方式

ActionContext創建好後會和當前線程綁定,若要獲取ActionContext對象只需從ThreadLocal中獲取即可。

(3)ActionContext訪問Servlet API的常用方法:

<1>void put(String key,Object value)

      功能描述:將key-value放進ActionContext中,模擬Servlet API中的HttpServletRequest中的setAttribute()方法。

<2>Oject get(String key) 功能描述:通過參數key獲取ActionContext中的value值

示例(獲取request域):

Map<String,Object> requestScope = (Map<String, Object>) ActionContext.getContext().get("request");

<3>Map<String ,Object> getApplication() 功能描述: 返回一個Application級的Map對象

示例:

Map<String, Object> applicationScope = ActionContext.getContext().getApplication();

applicationScope.put("name","applicationTom");

<4>static   ActionContext   getContext() 功能描述:獲取當前線程的ActionContext對象

示例:

ActionContext.getContext().put("name","requestTom");

<5>Map<String,Object> getParameters() 功能描述:返回一個包含所有HttpServletRequest信息的Map對象

<6>Map<String,Object> getSession() 功能描述:返回一個HttpSession級的Map對象

示例:

Map<String, Object> sessionScope = ActionContext.getContext().getSession();

sessionScope.put("name","sessionTom");

<7>void  setApplication(Map<String,Object>) 功能描述:設置Application上下文

<8>void  setSession(Map<String,Object>) 功能描述:設置Session

3  獲取原生ServletAPI問題

獲取原生的Servlet API方式一:

可使用stuts2提供的ServletActionContext類

代碼示例:

//獲取原生的request域

HttpServletRequest request = ServletActionContext.getRequest();

//獲取原生的session

HttpSession session = request.getSession();

//獲取原生的response域

HttpServletResponse response = ServletActionContext.getResponse();

//獲取原生的ServletContext

ServletContext servletContext = ServletActionContext.getServletContext();

//獲取原生的PageContext

PageContext pageContext=ServletActionContext.getPageContext();

獲取原生的Servlet API方式二:

通過實現接口來獲取 原生的 ServletAPI

代碼示例:

public class Demo6Action extends ActionSupport implements ServletRequestAware,ServletResponseAware,ServletContextAware{

private HttpServletRequest request;

private HttpServletResponse response;

private ServletContext context;

public String execute()throws Exception{

System.out.println(request);

return SUCCESS;

}

//獲取原生 request

@Override

public void setServletRequest(HttpServletRequest request) {

this.request=request;

}

//獲取原生的 response

@Override

public void setServletResponse(HttpServletResponse response) {

this.response=response;

}

//獲取原生的 ServletContext

@Override

public void setServletContext(ServletContext context) {

this.context=context;

}

}

5  獲取原生的request域問題。

HttpServletRequest request = ServletActionContext.getRequest();

分析:

struts2不推薦使用原生的request域,若想達到原生的request域的效果,可直接把數據存到ActionContext容器中,

因爲ActionContext的生命週期和原生的request一模一樣。

值得一提的是:把值放到ActionContext中,但取的方法卻是和原生的Request域一樣,

使用 request.getParameter("name"),原因是在struts2的核心過濾器中StrutsPrepareAndExecuteFilter

已經把request域對象進行包裝處理過了: request = prepare.wrapRequest(request);

## 結果頁面配置

1 概述:在struts.xml使用<result>標籤配置Result邏輯視圖和物理視圖之間的映射,<result>元素存在name,type常見屬性,

但這兩種屬性都不是必選的。

name屬性:指定邏輯視圖名稱,默認值爲success.

type屬性:指定返回視圖資源的類型,默認值爲dispatcher(請求轉發),還包括的爲redirect(重定向) ,

chain(轉發到另一個Action,少用),redirectAction(重定向到另一個Action,常用)

2 結果頁面配置

概述:在struts2的結果配置中,有兩種方式,全局結果頁面配置和局部結果頁面配置。

(1)全局結果頁面配置

全局結果頁面是指在同一個包下配置Action中返回相同的字符串的值,都可以跳轉到該頁面。

示例:

<global-results>

<result name="success">/success.jsp</result>

</global-results>

(2)局部結果頁面配置

局部結果頁面是隻針對某個Action,根據該字符串的值進行頁面跳轉。

示例:

<action name="Demo1Action"

class="cn.iesult.Demo1Action" method="execute">

<result name="success" type="dispatcher">/hello.jsp</result>

</action>

(3)結果頁面配置擴展瞭解

一個結果類型resultType接口com.opensymphony.xwork2.Result的實現。

struts2把內置的<result-type>都放在 struts2-core-2.3.24.jar/struts-default.xml文件中

## Struts2的數據封裝

1 概述:在實際開發中,Action會接收  頁面提交的請求參數,並將數據封裝到一個javaBean中,傳遞到業務層。

          struts2封裝數據的方式有兩種:屬性驅動(屬性set方法) 模型驅動(表達式方式)。

2 屬性驅動

(1)概述:直接在Action中定義各種Java基本數據類型的字段,使這些字段與表單數據相對應,並利用這些字段進行數據傳遞。

以前我們使用Serlvet只能在方法內獲取參數的原因是:

一個web應用只能有一個Servlet,意味着該Servlet的成員變量都是唯一的。

但是因爲Servelet是線程不安全的,當它的成員變量同時被幾個請求訪問時,就會出現被覆蓋的情況。

所以我們使用Servlet接收參數只能在方法內用局部變量接收,不能像Action這樣使用成員變量接收。

所以我們這裏可以使用成員變量接收參數--也表明我們的Action是線程安全的

每次請求Action時都會創建新的Action實例對象。

(2)方式一:在Action內定義屬性,通過提供屬性set方法來完成。

示例:

<form action="${pageContext.request.contextPath }/Demo8Action" method="POST">

用戶名:<input type="text" name="name"/><br>

年齡:<input type="text" name="age"/><br>

生日:<input type="text" name="birthday"/><br>

<input type="submit" value="提交" />

</form>

public class Demo8Action extends ActionSupport{

//接收姓名參數

private String name;

public void setName(String name) {this.name = name;}

//接收年齡參數--自動類型轉,只能轉換8大基本數據類型以及對應的包裝類

private Integer age;

public void setBirthday(Date birthday) {this.birthday = birthday;}

//接收日期參數--struts2支持特定類型字符串(yy-MM-dd)轉換爲Date

private Date birthday;

public void setAge(Integer age) {this.age = age;}

public String execute()throws Exception{

System.out.println("參數name爲:"+name+",參數age爲:"+age+",birthday:"+birthday);

return SUCCESS;

}

public Demo8Action() {

super();

System.out.println("創建了一個新的Action對象");

}

}

缺點:數據過於多時,會使Action非常臃腫。

(3)方式二:把屬性數據和對應的getter/setter方法抽取到一個javaBean類,Action直接使用javaBean即可。

此方式除了提供屬性的set方法還要有get方法,get方法用於獲取javaBean類中的屬性。

  同理,Action類中的javaBean對象也需要提供get/set方法。

示例:(注意此處jsp頁面的name屬性值與第一種方式的不同)

<form action="${pageContext.request.contextPath }/Demo10Action" method="POST">

用戶名:<input type="text" name="user.username"/><br>

年齡:<input type="text" name="user.age"/><br>

生日:<input type="text" name="user.birthday"/><br>

<input type="submit" value="提交" />

</form>

public class User {

private String Username;

private Long age;

private Date birthday;

public String getUsername() {return Username; }

//提供getter/setter方法

public void setUsername(String username) {Username = username;}

public Long getAge() {return age;}

public void setAge(Long age) {this.age = age;}

public Date getBirthday() {return birthday;}

public void setBirthday(Date birthday) {this.birthday = birthday;}

@Override

public String toString() {

return "User [Username=" + Username + ", age=" + age + ", birthday=" + birthday + "]";

}

}

public class Demo9Action extends ActionSupport{

private User user;

//提供javaBean類的getter/setter方法

public User getUser() {return user;}

public void setUser(User user) {this.user = user;}

public String execute()throws Exception{

System.out.println(user);

return SUCCESS;

}

public Demo9Action() {

super();

System.out.println("創建了一個新的Action對象");

}

對比方式一的不同之處:

(1)方式二jsp頁面的name屬性格式爲:user.name,user.age,user.birthday。

方式一的沒有user前綴

(2)方式二的封裝對象極其屬性必須要提供getter/setter方法

方法一:只需提供屬性的setter方法

3 模型驅動

(1)概述:

· 通過實現ModelDriven<>接口,複寫getModel()方法直接獲取Action數據模型對象(javaBean類型),

   與屬性驅動方式二都使用到javaBean對象,與之不同的是,

& 它不需提供javaBean對象的getter/setter方法。

& 它的jsp頁面name屬性沒有user對象前綴。

開發我們優先使用模型驅動,若有多個數據模型對象則是用屬性驅動的方式二獲取數據。

(2)示例:

<form action="${pageContext.request.contextPath }/Demo10Action" method="POST">

用戶名:<input type="text" name="username"/><br>

年齡:<input type="text" name="age"/><br>

生日:<input type="text" name="birthday"/><br>

<input type="submit" value="提交" />

</form>

public class Demo10Action extends ActionSupport implements ModelDriven<User>{

//複寫接口ModelDriven<User>的方法

@Override

public User getModel() {

return user;

}

private User user=new User();

public String execute()throws Exception{

System.out.println(user+"10----");

return SUCCESS;

}

public Demo10Action() {

super();

System.out.println("創建了一個新的Action對象");

}

}

4 struts2對集合對象的數據模型封裝

(1)概述:在開發中,我們需要批量插入用戶或其他對象。Action中可能會接受多個其他的Action封裝的對象,

         這時候我們需將表單數據封裝到集合中。我們一般使用的集合爲List或Map

(2)表單數據封裝到List集合中示例:

<form action="${pageContext.request.contextPath }/Demo11Action" method="POST">

list:<input type="text" name="list"/><br>

list:<input type="text" name="list[1]"/><br>

list:<input type="text" name="list[3]"/><br>

<input type="submit" value="提交" />

</form>

public class Demo11Action extends ActionSupport{

private List<String>list;

public List<String> getList() {return list;}

public void setList(List<String> list) {this.list = list;}

public String execute()throws Exception{

System.out.println("list:"+list);

return SUCCESS;

}

}

   (3)表單數據封裝到Map集合中示例:

<form action="${pageContext.request.contextPath }/Demo11Action" method="POST">

map:<input type="text" name="map['key1']"/><br/>

map:<input type="text" name="map['key2']"/>

<input type="submit" value="提交" />

</form>

public class Demo11Action extends ActionSupport{

private Map<String,String>map;

public Map<String, String> getMap() {return map;}

public void setMap(Map<String, String> map) {this.map = map;}

public String execute()throws Exception{

System.out.println(map);

return SUCCESS;

}

}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章