Struts2提供了了多种方式来访问上述的三种现象,归结起来,可以划分为两大类:与Servlet API 解耦的访问方式和与Servlet API耦合的访问方式。
一. 与Servlet API 解耦的访问方式
为了避免与Servlet API 耦合在一起,方便Action类做单元测试,Struts2对HttpServletRequest,HttpSession和ServletContext进行了封装,构造了三个Map对象来替代这三种对象,在Action中,直接使用HttpServletRequest,HttpSession和ServletContext对应的Map对象来保存和读取数据。
要获取这三个对象,可以使用com.opensymphont.xwork2.ActionContext类。
ActionContext是action执行的上下文,在ActionCOntext中保存了action执行所需的一组对象,包括parameters,request,session,application和locale等。ActionContext类定义了如下方法,用于获取HttpServletRequest,HttpSession和ServletContext对应的Map对象。
01.public Object get(Object key)
ActionContext类没有提供类似getRequest()这样的方法来过去封装了HttpServletRequest的Map对象。要得到请求Map对象,你需要为get()方法传递参数“request”。
02.public Map getSession()
获取封装了HttpSession的Map对象。
03.public Map getApplication()
获取封装了ServletCOntext的Map对象。
案例:登录进入成功页面,显示用户名。
package cn.action; import cn.entity.User; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.ServletActionContext; import java.util.Map; /** * Created by micro on 2017/10/21. */ public class LoginAction implements Action,ModelDriven{ private User user=new User(); public String execute() throws Exception { if ("admin".equals(user.getName())&&"123".equals(user.getPassword())){ //解耦方式 ActionContext context = ActionContext.getContext();
//request
Map request= (Map)context.get("request");
//application
Map application = context.getApplication();
//session
Map map.put("uname",user.getName());
//值栈 页面直接用 ${uname} 获取值
//方式一:
/*ValueStack valueStack = context.getValueStack();
valueStack.push(map);*/
//方式二:
HttpServletRequest request = ServletActionContext.getRequest();
ValueStack vs= (ValueStack)request.getAttribute("struts.valueStack");
vs.push(map);
return "success";
} return "input";
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Object getModel() {
return user;
}
}
struts.xml
xml version="1.0" encoding="UTF-8"?>
struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true"/>
<package name="default" namespace="/" extends="struts-default">
<action name="loginAction" class="cn.action.LoginAction">
<result name="success">/success.jspresult>
<result name="input">/login.jspresult>
action>
package>
struts>
login.jsp
<%@page language="java" contentType="text/html; utf-8" %>
<%@taglib uri="/struts-tags" prefix="s"%>
<title>登录title>
<html>
<body>
<s:form name="form1" namespace="/" method="POST" action="loginAction">
用户名:<s:textfield name="name">s:textfield>
密码: <s:textfield name="password">s:textfield>
<s:submit value="登录">s:submit>
s:form>
body>
html>
<%@page language="java" contentType="text/html; utf-8" isELIgnored="false" %>
<%@taglib uri="/struts-tags" prefix="s"%>
<html>
<body>
<
s
:property
value
="#session.uname"
/>
${uname}
body>
html>
除了利用ActionContext‘来获取request,session和application对象这种方式,Action类可以实现某些特定的接口,让Struts2框架在运行是向Action实例注入request,session和application对象。与之对应的三个接口和它们的方法如下:
二.与Servlet API 耦合的方式
public class LoginAction implements Action,ModelDriven{
private User user=new User();
public String execute() throws Exception {
if ("admin".equals(user.getName())&&"123".equals(user.getPassword())){
//耦合方式一:
HttpSession session = ServletActionContext.getRequest().getSession();
session.setAttribute("uname",user.getName());
ServletContext servletContext = ServletActionContext.getServletContext();
servletContext.setAttribute("unames",user.getName());
return "success";
}
return "input";
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Object getModel() {
return user;
}
package cn.action; import cn.entity.User; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.util.ValueStack; import org.apache.struts2.ServletActionContext; import org.apache.struts2.interceptor.ServletRequestAware; import org.apache.struts2.util.ServletContextAware; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; /** * Created by micro on 2017/10/21. */ public class LoginAction implements Action,ModelDriven,ServletRequestAware,ServletContextAware { private User user=new User(); HttpServletRequest request; ServletContext context; public String execute() throws Exception { if ("admin".equals(user.getName())&&"123".equals(user.getPassword())){ //耦合方式二:实现ServletRequestAware接口 给request对象赋值 ServletContextAware接口给contest对象注入 HttpSession session = request.getSession(); session.setAttribute("uname",user.getName()); return "success"; } return "input"; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Object getModel() { return user; } public void setServletRequest(HttpServletRequest httpServletRequest) { this.request=httpServletRequest; } public void setServletContext(ServletContext servletContext) { this.context=servletContext; } }
总结:
直接用action对象接收用户输入的数据,分别是Servlet API 解耦方式和Servlet API 耦合方式。