有关Struts2a的ction直接使用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运行完成返回数据给client;
        3)我们的Filter打印日志“结束执行”;
        4)ajax依据结果进行第二次訪问。

        可是假设我们採用上边的方式运行,则可能出现这样的顺序:

         1)我们的Filter打印日志“開始执行”;
         2)Struts2运行完成返回数据给client。
         3)ajax依据结果进行第二次訪问;
         4)我们的Filter打印日志“结束执行”;

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

         因此。在struts2一定要慎重直接使用response来完毕一些操作。

         解决的方法。能够使用struts2自回到自己json数据或二进制的方式将这些工作全部完成。


版权声明:本文博客原创文章,博客,未经同意,不得转载。

原文地址:https://www.cnblogs.com/mfrbuaa/p/4718051.html