我们想要访问Map类型request,session,application。真实类型HttpServletRequest,HttpSession,ServletContext的引用,并对它们进行操作。
这是我们的主页文件。
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 取得Map类型request,session,application。真实类型HttpServletRequest,HttpSession,ServletContext的引用 <br> <ol> <li>前三者依赖于容器</li> <li>前三者,IOC</li> <li>后三者,依赖于容器</li> <li>后三者,IOC</li> </ol> <form action="" name="f" method="post"> 用户名:<input type="text" name="name"/> 密码:<input type="text" name="password"/> <br> <input type="button" value="submit1" onclick="javascript:document.f.action='login/login1';document:f.submit();"> <input type="button" value="submit2" onclick="javascript:document.f.action='login/login2';document:f.submit();"> <input type="button" value="submit3" onclick="javascript:document.f.action='login/login3';document:f.submit();"> <input type="button" value="submit4" onclick="javascript:document.f.action='login/login4';document:f.submit();"> </form> </body> </html>
页面有四个按钮,单击后动态调用login/login*,然后提交。submit1 会调用Login1Action.java.
Login1Action.java
package com.tfj.struts2.action; import java.util.Map; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class Login1Action extends ActionSupport{ private Map request; private Map session; private Map application; public Login1Action() { request = (Map)ActionContext.getContext().get("request"); session = ActionContext.getContext().getSession(); application = ActionContext.getContext().getApplication(); } public String execute() { request.put("r1", "r1"); session.put("s1", "s1"); application.put("a1", "a1"); return SUCCESS; } }
在这个文件中,自己定义了Map类型的request,session,和application,通过ActionContext取得Action的上下文,在拿到request。在execute()方法对request赋值。在显示的页面loginsuccess.jsp显示出来。
loginsuccess.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'loginsuccess.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <s:property value="#request.r1"/> | <%=request.getAttribute("r1") %><br /> <s:property value="#session.s1"/> | <%=session.getAttribute("s1") %><br /> <s:property value="#application.a1"/> | <%=application.getAttribute("a1") %><br/> <br> </body> </html>
这里有两种调用方式<s:property value="#request.r1"/> 因为request是stack context里的内容 需要加#符号来调用里里面的内容(通过debug标签可以自己看),<%=request.getAttribute("r1") %>则是用javascript代码来调用。结果如图
接下来讲一种更为常用的,应该说最常用的方法,叫做DI(Dependeny Injection)依赖注入,也叫IoC(InversionofControl)控制反转。
单击submit2,调用Login2Action.java
Login2Action.java
package com.tfj.struts2.action; import java.util.Map; import org.apache.struts2.interceptor.ApplicationAware; import org.apache.struts2.interceptor.RequestAware; import org.apache.struts2.interceptor.SessionAware; import com.opensymphony.xwork2.ActionSupport; public class Login2Action extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{ private Map<String, Object> request; private Map<String,Object> session; private Map<String,Object> application; @Override public String execute() throws Exception { request.put("r1", "r1"); session.put("s1", "s1"); application.put("a1", "a1"); return SUCCESS; } @Override public void setApplication(Map<String, Object> application) { this.application=application; } @Override public void setSession(Map<String, Object> session) { // TODO Auto-generated method stub this.session=session; } @Override public void setRequest(Map<String, Object> request) { // TODO Auto-generated method stub this.request=request; } }
实现 RequestAware,SessionAware,ApplicationAware接口,实现对应的方法setRequest(Map<String, Object> request),setSession(Map<String, Object> session),setApplication(Map<String, Object> application)。为什么这种方法叫DI或IoC呢?
因为这种方法并不是request去取得一个值,而是询问request是否存在(requestAware接口),如果存在就调用setRequest()方法来给request初始化,叫做依赖注入。IoC反转控制也很好理解,本来的控制端被反转了。
这种方法最常用,要好好理解。
这是取得Map类型request,session,application。要取得真实类型HttpServletRequest,HttpSession,ServletContext的引用道理类似。submi3,是依赖容器的方法,submit4,是IoC,简单了解即可。
Login3Action.java
package com.tfj.struts2.action; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class Login3Action extends ActionSupport{ private HttpServletRequest request; private HttpSession session; private ServletContext application; public Login3Action() { request=ServletActionContext.getRequest(); session=request.getSession(); application=session.getServletContext(); } @Override public String execute() { request.setAttribute("r1", "r1"); session.setAttribute("s1", "s1"); application.setAttribute("r1", "r1"); return SUCCESS; } }
实现ServletRequestAware接口即可。
Login4Action.java
package com.tfj.struts2.action; import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.servlet.ServletRequestContext; import org.apache.struts2.ServletActionContext; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.util.ServletContextAware; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; public class Login4Action extends ActionSupport implements ServletRequestAware{ private HttpServletRequest request; private HttpSession session; private ServletContext application; @Override public void setServletRequest(HttpServletRequest request) { this.request=ServletActionContext.getRequest(); this.session=request.getSession(); this.application=session.getServletContext(); } @Override public String execute() { request.setAttribute("r1", "r1"); session.setAttribute("s1", "s1"); application.setAttribute("r1", "r1"); return SUCCESS; }