SSH入門Struts2篇(4)——Action類與servlet API
阿新 • • 發佈:2019-01-09
struts2的execute方法中並沒有任何引數(相較於servlet的doGet和doPost),不存在任何的servlet API。即Action類沒有與任何Servlet API耦合,因此可以脫離Servlet容器環境進行單元測試。
struts2提供以四種下方式訪問servlet API:
其中方法1和2保持了action與servlet API的解耦,而方法3和4中action與servlet API直接耦合
1.通過ActionContext類完成
//獲取ActionContext物件,每個Action例項都有一個ActionContext物件
ActionContext ctx = ActionContext.getContext();
//通過ActionContext物件獲取請求、會話和上下文物件相關聯的Map物件
Map request=(Map) ctx.get("request");
Map session=(Map) ctx.getSession();
Map application=(Map) ctx.getApplication();
application.put("xxx", xxx);
示例程式碼:
loginAction中的login方法:
public String login() {
ActionContext ctx = ActionContext. getContext();
//通過ActionContext物件獲取請求、會話和上下文物件相關聯的Map物件
Map request=(Map) ctx.get("request");
Map session=(Map) ctx.getSession();
Map application=(Map) ctx.getApplication();
//訪問application範圍的屬性值
Integer counter = (Integer)application.get("counter");
if(counter == null)
counter = 1;
else
counter++;
//設定application範圍的屬性
application.put("counter", counter);
UserService userServ = new UserService();
if(userServ.login(loginUser)) {
//設定session範圍的屬性
session.put("user", loginUser.getAccount());
//設定request範圍的屬性
request.put("tip", "您已登入成功");
return "loginsuccess";
}
this.addActionError(this.getText("login.fail"));
return "loginfail";
}
loginSuccess.jsp:
<body>
本站訪問次數為:<s:property value="#application.counter"/><br>
<s:property value="#session.user"/>
<s:property value="#request.tip"/>
</body>
2.實現***Aware介面(RequestAware、SessionAware和ApplicationAware)
注意在這裡要宣告私有屬性,因此login方法也和前面有所不同,不需要再進行宣告。
public class UserAction extends ActionSupport implements
RequestAware,SessionAware,ApplicationAware {
private Map request,session,application;
……
public void setRequest(Map<String, Object> request) {
this.request=request; }
public void setSession(Map<String, Object> session) {
this.session=session; }
public void setApplication(Map<String, Object> application) {
this.application=application; }
……
public String login(){
//訪問application範圍的屬性值
Integer counter = (Integer)application.get("counter");
if(counter == null)
counter = 1;
else
counter++;
//設定application範圍的屬性
application.put("counter", counter);
UserService userServ = new UserService();
if(userServ.login(loginUser)) {
//設定session範圍的屬性
session.put("user", loginUser.getAccount());
//設定request範圍的屬性
request.put("tip", "您已登入成功");
return "loginsuccess";
}
this.addActionError(this.getText("login.fail"));
return "loginfail";
}
}
loginSuccess.jsp與第一種方法時相同
3.servletActionContext工具類
注意這裡不再用.set()和.put()方法了,而是使用setAttribute()和getAttribute()
public class UserAction extends ActionSupport {
……
public String login(){
HttpServletRequest request = ServletActionContext.getRequest();
//HttpServletResponse response = ServletActionContext.getResponse();
ServletContext application = ServletActionContext.getServletContext();
HttpSession session = request.getSession();
//訪問application範圍的屬性值
Integer counter = (Integer)application.getAttribute("counter");
if(counter == null)
counter = 1;
else
counter++;
//設定application範圍的屬性
application.setAttribute("counter", counter);
UserService userServ = new UserService();
if(userServ.login(loginUser)) {
//設定session範圍的屬性
session.setAttribute("user", loginUser.getAccount());
//設定request範圍的屬性
request.setAttribute("tip", "您已登入成功");
return "loginsuccess";
}
this.addActionError(this.getText("login.fail"));
return "loginfail";
}
}
4.通過實現介面:ServletContextAware、ServletRequestAware、ServletResponseAware
public class UserAction extends ActionSupport implements ServletRequestAware, ServletContextAware{
private ServletContext application;
private HttpServletRequest request;
private HttpSession session;
……
public String login() {
//訪問application範圍的屬性值
Integer counter = (Integer)application.getAttribute("counter");
if(counter == null)
counter = 1;
else
counter++;
//設定application範圍的屬性
application.setAttribute("counter", counter);
UserService userServ = new UserService();
if(userServ.login(loginUser)) {
//一定要記得getSession
session = request.getSession();
//設定session範圍的屬性
session.setAttribute("user", loginUser.getAccount());
//設定request範圍的屬性
request.setAttribute("tip", "您已登入成功");
return "loginsuccess";
}
this.addActionError(this.getText("login.fail"));
return "loginfail";
}
@Override
public void setServletContext(ServletContext application) {
// TODO Auto-generated method stub
this.application = application;
}
@Override
public void setServletRequest(HttpServletRequest request) {
// TODO Auto-generated method stub
this.request = request;
}
}
但是要注意不使用servlet API的時候也是可以在跳轉到的介面獲取值的
因為result的type屬性預設值是dispatcher,就相當於在servlet中的.forward,所以至少同一個request下的變數還是可以在跳轉到的頁面共享的
在Action中:
package cn.edu.zjut.action;
import java.util.List;
import cn.edu.zjut.service.ItemService;
public class ItemAction{
private List items;
ItemService itemServ;
public String getAllItems() {
itemServ = new ItemService();
if(itemServ.getAllItems() != null) {
items = itemServ.getAllItems();
return "success";
}
return "fail";
}
public List getItems() {
return items;
}
}
返回success後對應的.jsp頁面:
<body>
<table border="1">
<tr>
<th>編號</th><th>書名</th><th>說明</th><th>單價</th>
</tr>
<s:iterator value="items">
<tr>
<!-- 這是主鍵為itemID時的寫法
<td><s:property value="itemID"/></td>
<td><s:property value="name"/></td>
-->
<!-- 在這裡主鍵是ipk,即itemID和name構成複合主鍵 -->
<td><s:property value="ipk.itemID"/></td>
<td><s:property value="ipk.name"/></td>
<td><s:property value="description"/></td>
<td><s:property value="cost"/></td>
</tr>
</s:iterator>
</table>
</body>
注意在這裡,要讓jsp獲取到items,首先在Action中要有items這個私有屬性,然後要提供這個屬性的get方法,不然jsp頁面是獲取不到的。
當然action中也可以用上面四種servlet API的方法,比如說把它存到session裡面,那麼在jsp中只需要<s:iterator value="#session.items">