1. 程式人生 > >SSH入門Struts2篇(4)——Action類與servlet API

SSH入門Struts2篇(4)——Action類與servlet API

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">