概念:
耦合是指兩個或兩個以上的體系或兩種運動形式間通過相互作用而彼此影響以至聯合起來的現象。
什么是與Servlet API解耦?
為了避免與servlet API耦合在一起,方便Action做單元測試,
Struts2對HttpServletRequest,HttpSession,和ServletContext進行了封裝,構造了3個Map對象來替代這三個對象,在Action中可以直接使用HttpServletRequest,HttpSession,ServletContext對應的Map對象來保存和讀取數據。
兩種解耦方式:
1、 使用Struts2提供的工具類中提供的靜態方法,得到對用的封裝后對象。
package cn.itcast.context; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class ContextAction extends ActionSupport { /** * */ private static final long serialVersionUID = 1L; public String test() throws Exception{ System.out.println("ContextAction ****** test()"); HttpServletRequest request=ServletActionContext.getRequest(); request.setAttribute("username","username_request"); HttpServletResponse response=ServletActionContext.getResponse(); Map sessionMap=ServletActionContext.getContext().getSession(); sessionMap.put("username", "username_session"); ServletContext sc=ServletActionContext.getServletContext(); sc.setAttribute("username", "username_application"); return "attr"; } }
2、 Action實現ServletRequestAware,ServletResponseAware,ServletContextAware,SessionAware四個接口,分別重寫對應的set方法,達到操作該4個封裝后對象。
package cn.itcast.context; import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.struts2.ServletActionContext; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.interceptor.ServletResponseAware; import org.apache.struts2.interceptor.SessionAware; import org.apache.struts2.util.ServletContextAware; import com.opensymphony.xwork2.ActionSupport; public class Context02Action extends ActionSupport implements ServletRequestAware,ServletResponseAware,ServletContextAware,SessionAware{ HttpServletRequest request; HttpServletResponse response; ServletContext context; Map<String, Object> sessionMap; private static final long serialVersionUID = 1L; public String test() throws Exception{ System.out.println("ContextAction ****** test()"); HttpServletRequest request=ServletActionContext.getRequest(); request.setAttribute("username","username_request"); HttpServletResponse response=ServletActionContext.getResponse(); Map sessionMap=ServletActionContext.getContext().getSession(); sessionMap.put("username", "username_session"); ServletContext sc=ServletActionContext.getServletContext(); sc.setAttribute("username", "username_application"); return "attr"; } public void setSession(Map<String, Object> session) { this.sessionMap=session; } public void setServletContext(ServletContext context) { this.context=context; } public void setServletResponse(HttpServletResponse response) { this.response=response; } public void setServletRequest(HttpServletRequest request) { this.request=request; } }
其他代碼:




struts2與servlet的耦合有三種實現方案:
1.ActionContext
在xwork2.jar的com.opensymphony.xwork2.ActionContext中。
這個是最推薦的一種實現。
action不需要實現接口,只需要引入這個目錄就可以。
只需要一句代碼就可以放入response中,頁面直接用EL表達式${requestScope.zhangsan}獲取。取代了標簽
2.servletActionContext
在struts2-core.jar中,org.apache.struts2.ServletActionContext
同樣action不需要實現接口,只需要引入這個目錄就可以。
實現了response對象,然后只需要像往常一樣適用
cookie.setMaxAge(1000);
response.addCookie(cookie);
3.ServletRequestAware,ServletResponseAware接口實現
首先實現接口,然后實現request或response對象。



public class LoginAction extends ActionSupport implements ServletRequestAware {
private static final long serialVersionUID = 3936066275134469754L;
// private HttpServletResponse response;
private HttpServletRequest request;
@SuppressWarnings("unchecked")
public String execute() throws Exception {


}
@SuppressWarnings("unchecked")
public String hello() throws Exception {


request.setAttribute("zhangsan","helloworld");


}
public void setServletRequest(HttpServletRequest request) {
this.request=request;
}
}
Action類案例:
public class FirstAction implements Action,ModelDriven<UserInfo>,ServletRequestAware{ private Map<String, Object> map; private HttpServletRequest request; //前台輸入的用戶名和密碼 在Action中如何捕獲 private UserInfo user=new UserInfo(); public String execute() throws Exception { System.out.println("====FirstAction ==============+++execute"); System.out.println("================="+user); if(user.getUsername().equals("admin")&&user.getPassword().equals("admin")){ //解耦合方式一 //Map<String, Object> session = ActionContext.getContext().getSession(); //解耦合方式2:IOC(注入)SessionAware //耦合方式一 /*HttpSession session2 = ServletActionContext.getRequest().getSession(); //耦合方式2 Map<String, Object> session = ServletActionContext.getContext().getSession(); */ //session.put("uname", user.getUsername()); //session2.setAttribute("uname", user.getUsername()); //map.put("uname", user.getUsername()); request.getSession().setAttribute("uname", user.getUsername()); return "success"; }else{ return "login"; } } public Map<String, Object> getMap() { return map; } public void setMap(Map<String, Object> map) { this.map = map; } public HttpServletRequest getRequest() { return request; } public void setRequest(HttpServletRequest request) { this.request = request; } public UserInfo getUser() { return user; } public void setUser(UserInfo user) { this.user = user; } public UserInfo getModel() { return null; } public void setServletRequest(HttpServletRequest request) { this.request=request; } public void setSession(Map<String, Object> map) { this.map=map; } }