Struts2 第五讲 -- Struts2与Servlet的API解耦
为了避免与 Servlet API 耦合在一起, 方便 Action 做单元测试, Struts2 对 HttpServletRequest, HttpSession 和 ServletContext 进行了封装, 构造了 3 个 Map 对象来替代这 3 个对象, 在 Action 中可以直接使用 HttpServletRequest, HttpSession, ServletContext 对应的 Map 对象来保存和读取数据。这里大家注意,struts1是没有提供与Servlet的API解耦的。
1.Struts2如何获取request、response、session、ServletContext
在Struts2开发中,除了将请求参数自动设置到Action的字段中,我们往往也需要在Action里直接获取请求(Request)或会话(Session)的一些信息,甚至需要直接对JavaServlet Http的请求(HttpServletRequest),响应(HttpServletResponse)操作.Struts2提供了三种用于获取这些对象的方法,下面来一一介绍一下;
非IOC方法:通过ActionContext,ServletActionContext类直接获取,实现与Servlet解耦
- l ActionContext是 Action 执行的上下文对象, 在 ActionContext 中保存了 Action 执行所需要的所有对象, 包括 parameters, request, session, application 等.
static ThreadLocal actionContext = new ActionContextThreadLocal()
(ActionContext) actionContext.get();来获取
- l 获取 HttpServletRequest 对应的 Map 对象:public Object get(Object key): ActionContext 类中没有提供类似 getRequest() 这样的方法来获取 HttpServletRequest 对应的 Map 对象. 要得到 HttpServletRequest 对应的 Map 对象, 可以通过为 get() 方法传递 “request” 参数实现
ActionContext.get(org.apache.struts2.StrutsStatics.HTTP_REQUEST);
- 获取HTTPServletResponse,该获取同request相似;
ActionContext.get(org.apache.struts2.StrutsStatics.HTTP_RESPONSE);
- l 获取 HttpSession 对应的 Map 对象:
public Map getSession()
- l 获取 ServletContext 对应的 Map 对象:
public Map getApplication()
测试代码:获取request、response、session、application对象
@SuppressWarnings("serial")
public class ContextAction extends ActionSupport{
@Override
public String execute() throws Exception {
System.out.println("欢迎访问ContextAction中的execute方法!");
/**request对象(与servletAPI解耦的方式)*//*
ActionContext.getContext().put("username", "request_username");
*//**session对象(与servletAPI解耦的方式)*//*
ActionContext.getContext().getSession().put("username", "session_username");
*//**application对象(ServletContext对象)(与servletAPI解耦的方式)*//*
ActionContext.getContext().getApplication().put("username", "application_username");
*/
//使用与ServletActionContext的方式操作上述
ServletActionContext.getRequest().setAttribute("username", "request_username");
ServletActionContext.getServletContext().setAttribute("username", "application_username");
ServletActionContext.getRequest().getSession().setAttribute("username", "session_username");
System.out.println("request:"+ServletActionContext.getRequest());
System.out.println("response:"+ServletActionContext.getResponse());
System.out.println("session:"+ServletActionContext.getRequest().getSession());
System.out.println("servletContext:"+ServletActionContext.getServletContext());
//Action接口中常量 SUCCESS="success"
return SUCCESS;
}
}


IOC方法:实现指定接口,由struts框架运行时注入,即使用Struts2 Aware拦截器
Action 类通过可以实现某些特定的接口, 让Struts2 框架在运行时向 Action 实例注入 parameters, request, session 和 application 对应的 Map 对象:
测试代码::获取request、response、session、application对象
@SuppressWarnings("serial")
public class ContextActionTwo extends ActionSupport implements ServletRequestAware,
ServletContextAware,ServletResponseAware,SessionAware{
private HttpServletRequest request;
private HttpServletResponse response;
private Map<String, Object> session;
private ServletContext application;//注意可以实现接口ApplicationAware同样的功能
//使用第二种方式
@Override
public String execute() throws Exception {
System.out.println("欢迎访问ContextActionTwo中的execute()!");
//向作用域中存值
request.setAttribute("username", "request_username2");
session.put("username", "session_username2");
application.setAttribute("username", "application_username2");
return SUCCESS;
}
@Override
public void setSession(Map<String, Object> session) {
// TODO Auto-generated method stub
this.session = session;
}
@Override
public void setServletResponse(HttpServletResponse response) {
// TODO Auto-generated method stub
this.response = response;
}
@Override
public void setServletContext(ServletContext context) {
// TODO Auto-generated method stub
this.application = context;
}
@Override
public void setServletRequest(HttpServletRequest request) {
// TODO Auto-generated method stub
this.request = request;
}
}
attr.jsp <body>123
${requestScope.username}<br>
${sessionScope.username}<br>
${applicationScope.username}<br>
</body>

struts-context.xml文件的配置:
<struts>
<package name="context" namespace="/context" extends="struts-default">
<default-action-ref name="contextAction_test"></default-action-ref> <action name="contextAction_test" class="cn.youric.you.two_context.ContextAction">
<result name="success">/context/success.jsp</result>
</action>
<action name="contextAction02_test" class="cn.youric.you.two_context.ContextActionTwo">
<result name="success">/context/attr.jsp</result>
</action>
</package>
</struts>
别忘了include;
2.聊聊ActionContext
ActionContext(com.opensymphony.xwork.ActionContext)是Action执行时的上下文,上下文可以看作是一个容器(其实我们这里的容器就是一个Map而已),它存放的是Action在执行时需要用到的对象. 一般情况, 我们的ActionContext都是通过: ActionContext context = (ActionContext) actionContext.get();来获取的.我们再来看看这里的actionContext对象的创建:
static ThreadLocal<ActionContext> actionContext = new ThreadLocal<>();
ThreadLocal可以命名为"线程局部变量",它为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突.这样,我们ActionContext里的属性只会在对应的当前请求线程中可见,从而保证它是线程安全的.
3. ServletActionContext和ActionContext联系
ServletActionContext和ActionContext有着一些重复的功能,在我们的Action中,该如何去抉择呢?我们遵循的原则是:如果ActionContext能够实现我们的功能,那最好就不要使用ServletActionContext,让我们的Action尽量不要直接去访问Servlet的相关对象.
注意:在使用ActionContext时有一点要注意: 不要在Action的构造函数里使用ActionContext.getContext(),因为这个时候ActionContext里的一些值也许没有设置,这时通过ActionContext取得的值也许是null;同样,HttpServletRequest req = ServletActionContext.getRequest()也不要放在构造函数中,也不要直接将req作为类变量给其赋值。至于原因,我想是因为前面讲到的static ThreadLocal actionContext = new ActionContextThreadLocal(),从这里我们可以看出ActionContext是线程安全的,而ServletActionContext继承自ActionContext,所以ServletActionContext也线程安全,线程安全要求每个线程都独立进行,所以req的创建也要求独立进行,所以ServletActionContext.getRequest()这句话不要放在构造函数中,也不要直接放在类中,而应该放在每个具体的方法体中(eg:login()、queryAll()、insert()等),这样才能保证每次产生对象时独立的建立了一个req。
Struts2 第五讲 -- Struts2与Servlet的API解耦的更多相关文章
- Struts2(七) Struts2访问Servlet的API
当接受表单参数,向页面保持数据时.要用到Struts访问Servlet 的API .下面只做参考,有错误或不同意见可以发送邮箱2440867831@qq.com .建议大家看struts文档,源代码 ...
- 关于Struts2自动装配和访问Servlet API
自动装配 1.根据属性的getter和setter获取值 index.jsp <s:form action="hello" method="POST"& ...
- Struts2框架中使用Servlet的API示例
1. 在Action类中也可以获取到Servlet一些常用的API * 需求:提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的 ...
- 在Struts2框架中使用Servlet的API
1. 在Action类中也可以获取到Servlet一些常用的API * 需求:提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的 ...
- struts2:在Action中使用Servlet的API,设置、读取各种内置对象的属性
有两种方式可以实现在Action中使用Servlet的API.一种是使用org.apache.struts2.ServletActionContext类,另一种是使用com.opensymphony. ...
- struts2訪问servlet的API
1.struts作为控制器,正常非常多时候要訪问到servlet的API.经常使用功能: (1).获取请求參数,控制界面跳转 (2).把共享数据存储于request,session,servl ...
- Struts2(二)— Result结果配置、Servlet的API的访问、模型驱动、属性驱动
一.Result结果配置 1.全局和局部结果 平常我们设置跳转页面,是在action标签里面加上 result标签来控制,这种设置的页面跳转,称之为局部结果页面但是我们有时候在很多个action里 ...
- Struts2页面配置和访问servlet API
一.Struts2页面配置 在struts2中页面可以分为两种,全局页面和局部页面. 1.全局页面: 在一个<package></package>标签内的多个action都要跳 ...
- Struts2获取Servlet的api的两种方式,解决ParameterAware过时的问题
servlet API通过ActionContext进行获取 Struts2对HttpServletRequest,HttpSession和ServletContext进行了封装,构造了3个Map对象 ...
随机推荐
- PLC总结
PLC编程总结 PLC控制部分总体有三大部分组成,PLC硬件,组态以及梯形图程序.PLC硬件应与组态一一对应,不容有任何偏差:而梯形图与操作的组态的IO口也应该一一对应.因此,整个系统达到了由梯形图程 ...
- div居中方法总结
在日常开发过程中,我们会经常使用到div居中来处理布局,今天我就把我在开发过程中,遇到的div居中处理方法总结一下,方便日后查看! 1. 水平居中:给div设置一个宽度,然后添加marg ...
- spring+springmvc+hibernate整合遇到的问题
spring+springmvc+hibernate整合遇到的问题2016年10月20日 23:24:03 守望dfdfdf 阅读数:702 标签: ssh学习经历的异常exception异常框架更多 ...
- Dubbo与Zookeeper、Spring整合使用 maven+springmvc+dubbo+zookeeper
为什么要用dubbo? 还是让官方来解释吧: http://dubbo.io/User+Guide-zh.htm http://dubbo.io/ 一般 nginx+tomcat | - ...
- LOJ#2552. 「CTSC2018」假面(期望 背包)
题意 题目链接 Sol 多年以后,我终于把这题的暴力打出来了qwq 好感动啊.. 刚开始的时候想的是: 设\(f[i][j]\)表示第\(i\)轮, 第\(j\)个人血量的期望值 转移的时候若要淦这个 ...
- 原生js封装十字参考线插件(一)
需求来源: 拓扑图之机房平面图,显示机房长宽比例尺,房间内标注各种设备间距不易实现,特在机房平面图上层加一个十字参考线 横竖两条线垂直,在鼠标指针处交叉,显示鼠标指针坐标(相对机房平面图的坐标,不是相 ...
- css box-shadow知识点及多重边框
box-shadow() 参数: h-shadow:水平阴影的位置.允许负值. v-shadow:垂直阴影的位置.允许负值. blur:模糊距离. spread:扩张半径(可正可负.投影面积则可大可小 ...
- CentOS安装chrome-浏览器
首先,在CentOS中安装软件,通过yum命令来安装软件,就要在系统中的软件源中添加软件源节点,即在目录./etc/yum.repos.d/下的CentOS-Base.repo文件中做修改:在控制台C ...
- redis的使用方式
常用的语法以及使用方式: key中不能包含回车空格等,key不要太长,占用内存. 概念介绍: 差集: a:{1,2,3} b:{2,3,4},以a为锚点,差集 ...
- Flask入门flask-script 蓝本 钩子函数(三)
1 flask-script扩展库 概念: 是一个flask终端运行的解析器 ,因为项目完成以后,代码改动会有风险,所以借助终端完成不同启动项的配置 安装 pip3 install flask-scr ...