关于在Struts2的action中直接使用response的异步问题

如果我们项目中使用了struts2,在使用ajax和后端程序进行通讯时,我们常常为了简单采用以下的方法:

ActionContext ac = ActionContext.getContext();

HttpServletResponse response = (HttpSevletResponse)ac.get(StrutsStatics.HTTP_RESPONSE);

response.setContentType("text/html;charset=utf-8");

try {

PrintWriter pw = response.getWriter();

pw.print(data);

} catch(IOException e) {

e.printStackTrace();

}

以上的方法实际上是存在一个漏洞的。因为这个破坏了struts2执行的完整性,在程序运行过程中可能会出现执行步骤颠倒的问题,当然了这种方式带来的其他问题比如和servlet耦合等问题不是这里要讨论的。比如存在以下的一个场景:我们前端页面中使用ajax和后台进行通信,获取后台数据后,根据这个数据来访问程序中其他的URL路径。现在我们在web.xml中配置我们自己的Filter,这个Filter在struts2执行之前记下“开始运行”的日志,在Struts2执行完毕之后再记下“结束运行”的日志。严格意义上正确的执行顺序是:

1)我们的Filter打印日志“开始运行”;

2)Struts2执行完毕返回数据给客户端;

3)我们的Filter打印日志“结束运行”;

4)ajax根据结果进行第二次访问;

但是如果我们采用上边的方式执行,则可能出现这种顺序:

1)我们的Filter打印日志“开始运行”;

2)Struts2执行完毕返回数据给客户端;

3)ajax根据结果进行第二次访问;

4)我们的Filter打印日志“结束运行”;

原因可能是我们调用response的Writer返回数据给客户端时,会新开一个线程来完成这个工作,而struts2在继续完成其他的工作.某些情况下response的工作在struts2完成之前就完成了和客户端的交互,(比如使用struts2的result拦截器完成的工作比较耗时)。如果在正常流程中的第4)步会依赖第3)步的操作,比如完成设置数据到session,在苛刻的环境中第4)步访问过来了,结果第3)步仍然没有设置完毕(比如我们包装了request来解决分布式session的问题,因为分布式缓存来缓存session,如果session比较大或者嵌套比较复杂会比较耗时的情况下)就会出问题。

因此,在struts2一定要谨慎直接使用response来完成一些操作。

解决办法,可以使用struts2自己的返回json数据或者二进制的方式来完成这些工作。

时间: 2024-10-02 18:55:12

关于在Struts2的action中直接使用response的异步问题的相关文章

在Struts2的Action中获得request response session几种方法

转载自~ 在Struts2中,从Action中取得request,session的对象进行应用是开发中的必需步骤,那么如何从Action中取得这些对象呢?Struts2为我们提供了四种方式.分别为servlet 不相关的 非IoC 取得Request等对象的方式servlet 不相关的 IoC 取得Request等对象的方式servlet 相关的 非IoC 取得Request等对象的方式servlet 相关的 IoC 取得Request等对象的方式以下分别叙述.首先请看struts.xml文件文

struts2的action中获得request response session 对象

在struts2中有两种方式可以得到这些对象 1.非IoC方式 要获得上述对象,关键Struts 2中com.opensymphony.xwork2.ActionContext类.我们可以通过它的静态方法getContext()获取当前Action的上下文对象.有了这个对象我们想获得其他几个对象就好办了 ActionContext ctx = ActionContext.getContext(); Map session = ctx.getSession(); 细心的朋友可以发现这里的sessi

【JAVA学习】struts2的action中使用session的方法

尊重版权:http://hi.baidu.com/dillisbest/item/0bdc35c0b477b853ad00efac 在Struts2里,如果需要在Action中使用session,可以通过下面两种方式得到1.通过ActionContext class中的方法getSession得到2.Action实现org.apache.struts2.interceptor.SessionAware接口的方式来对session进行操作 下面先看一个采用第一种方式,在action中得到sessi

在struts2的action中操作域对象(request、session)

在struts2的Action中,操作域对象一共有三种方式: 1.ActionContext(与servelt API无关联): 1 //相当于request 2 ActionContext.getContext().put("userName", user.getUserName()); 3 //相当于session 4 ActionContext.getContext().getSession().put("userName", user.getUserName

Struts2 的Action中取得请求参数值的几种方法

Struts2 的Action中取得请求参数值的几种方法 先看GetRequestParameterAction类代码: Java代码 public class GetRequestParameterAction extends ActionSupport { private String bookName; private String bookPrice; public String getBookName() { return bookName; } public void setBook

理解Struts2的Action中的setter方法是怎么工作的

接触过webwork和Struts2的同行都应该知道, 提交表单的时候,只要Action中的属性有setter 方法,这些表单数据就可以正确赋值到Action中属性里:另外对于Spring配置文件中声明的bean,也可以在Action中声明setter 方法将其注入到Action实例中.那么现在要研究:这些是怎么工作的呢? (1)提交表单时的参数 在struts2-core-2.3.1.2.jar压缩包内的struts-default.xml配置文件中有这个配置:<interceptor nam

在Struts2的Action中取得请求参数值的几种方法

把参数放到作用域里面去. 如:action 中: request.setAttribute("参数名","值");   页面上:  request.getAttribute("参数名"); request.getParameter()方法完全可以获得URL参数,检查下是否参数名写错 你使用的是不是BaseAction.如果就是server.getRequest().getParameter() 看看你的控件是不是 name 属性!如果id的话就获

struts2在action中获取request、session、application,并传递数据

如果只是通过request.session.application传递数据,则不需要获取相应的对象也可以传递数据,代码如下: ScopeAction.java: package com.itheima.action; import com.opensymphony.xwork2.ActionContext; public class ScopeAction { public String execute() { /* * 我们这里不通过字段(添加setXXX.getXXX方法)传递数据,我们想着

9.Struts2在Action中获取request-session-application对象

为避免与Servlet API耦合在一起,方便Action类做单元测试. Struts2对HttpServletRequest.HttpSession.ServletContext进行了封装,构造了三个Map对象来替代这三种对象. 注意,这三个对象与Servlet API中的三个对象是相同的. 即,在Action中放入Session中信息,在JSP页面中是可以读出来的. 方式一:通过使用ActionContext类获取 在Struts2框架中,通过Action的执行上下文类ActionConte