Struts2 Interceptor *after* JSP 呈现 - 如何?

发布于 2024-08-03 11:31:33 字数 182 浏览 6 评论 0原文

我想知道在结果返回并呈现 JSP 后是否可以捕获操作的结果。我希望能够获取整个结果(生成的 HTML)并将其推送到 memcached 中,这样我就可以通过 Nginx 获取它,而无需访问应用程序服务器。有什么想法吗?

PS:我知道我可以在操作执行之后、结果返回和渲染 JSP 之前运行拦截器,但不能在渲染 JSP 之后运行拦截器。

I was wondering if I can capture the result of an action after the result returns and the JSP is rendered. I want to be able to take the entire result (generated HTML) and push it into memcached so I can bring it via Nginx with-out hitting the application server. Any ideas?

PS: I know I can run the interceptor after the action executes but before the result returns and the JSP is rendered, but not after the JSP is rendered.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

匿名。 2024-08-10 11:31:33

我还没有找到在 struts2 内部执行此操作的方法,最好的办法是创建一个 servlet Filter 并让它修改 OutputStream。

http://onjava.com/pub/a/onjava/ 2003/11/19/filters.html

I haven't found a way to do this inside of struts2, your best bet it to create a servlet Filter and have it modify the OutputStream.

http://onjava.com/pub/a/onjava/2003/11/19/filters.html

酒废 2024-08-10 11:31:33

嘿,我知道现在回答已经很晚了,您可能已经找到了答案,但是为了其他人受益,我发布了答案。
与您正在做的事情非常相似的一件事是由 sitemesh 过滤器完成的。
是的,过滤器位于 Struts2 过滤器本身之前和之后,因此您可以轻松地弄乱输入和输出。
但 struts 确实评估 JSP/freemarker/velocity 并生成传递给用户的最终 html。 JSP 有点棘手,因为内部调用了一个 servlet,但是查看 org.apache.struts2.views.freemarker.FreemarkerResult 类,您可以看到在 template.process(模特、作家);。这个writer实际上是ServletActionContext.getResponse().getWriter()

现在要获取 html,您需要做的就是
ServletActionContext.getResponse().getWriter().toString() //这不能开箱即用。要让 toString() 工作,您需要使用 ResponseWrapper - 这与在过滤器中获取结果 html 的方法相同。请参阅编程自定义请求和响应

列出在 struts 2 中修改生成的 html。这尚未经过测试,但它是从我之前为自定义模板引擎编写的代码中提取的。我可能会在Struts2的自定义模板引擎中发布完整的描述

public class DecoratorInterceptor implements Interceptor {
    public String intercept(ActionInvocation invocation) throws Exception {
       final ActionContext context = invocation.getInvocationContext ();
       HttpServletResponse responseParent = (HttpServletResponse) 
                               context.get(ServletActionContext.HTTP_RESPONSE);
       CharResponseWrapper wrapper = new CharResponseWrapper(responseParent);

       ServletActionContext.setResponse(wrapper);

       //Actual Action called
       String result =  invocation.invoke();

       String htmlReturned = wrapper.toString();
       //play with htmlReturned ...
       String modifiedhtml = pushintoMemCache(htmlReturned );           

       CharArrayWriter car = new CharArrayWriter();           
       car.write(modifiedhtml );

       PrintWriter out = responseParent.getWriter();
        out.write(car.toString());
        out.flush();
   }

  @Override
    public void destroy() {
    // TODO Auto-generated method stub

    }

  @Override
    public void init() {
    // TODO Auto-generated method stub

    }

}         

Hey I know its quite late now to answer you might have already found out the answer, however for others to benefit I am posting the answer.
One thing that is very similar to what you are doing is done by sitemesh filter.
Yes, filter comes before and after the Struts2 filter itself, so you can mess with the inputs and outputs easily.
But struts does evaluate JSP/freemarker/velocity and generate the final html which is passed to the user. JSP is a bit trickey because internally a servlet is called but check out org.apache.struts2.views.freemarker.FreemarkerResult class, you can see the actual html getting generated in template.process(model, writer);. This writer is actually ServletActionContext.getResponse().getWriter();

Now to get the html all you need to do is
ServletActionContext.getResponse().getWriter().toString() //This does not work out of box. To get the toString() to work you need to use a ResponseWrapper - which is the same method to get result html in Filters. See- Programming Customized Requests and Responses.

Listing to modify resulting html in struts 2. This is not tested, but it is extracted from my code I have written earlier for custom template engine. I will probably post full description in Custom template engine for struts2

public class DecoratorInterceptor implements Interceptor {
    public String intercept(ActionInvocation invocation) throws Exception {
       final ActionContext context = invocation.getInvocationContext ();
       HttpServletResponse responseParent = (HttpServletResponse) 
                               context.get(ServletActionContext.HTTP_RESPONSE);
       CharResponseWrapper wrapper = new CharResponseWrapper(responseParent);

       ServletActionContext.setResponse(wrapper);

       //Actual Action called
       String result =  invocation.invoke();

       String htmlReturned = wrapper.toString();
       //play with htmlReturned ...
       String modifiedhtml = pushintoMemCache(htmlReturned );           

       CharArrayWriter car = new CharArrayWriter();           
       car.write(modifiedhtml );

       PrintWriter out = responseParent.getWriter();
        out.write(car.toString());
        out.flush();
   }

  @Override
    public void destroy() {
    // TODO Auto-generated method stub

    }

  @Override
    public void init() {
    // TODO Auto-generated method stub

    }

}         
不乱于心 2024-08-10 11:31:33

阅读这篇文章 - http://struts.apache.org/2.0.6/文档/拦截器.html

摘要:当您请求资源时
映射到一个“动作”,
框架调用 Action 对象。
但是,在执行该操作之前,
调用可以被拦截
另一个物体。行动后
执行时,调用可以是
再次被拦截。不出所料,我们
将这些对象称为“拦截器”。

Read this article - http://struts.apache.org/2.0.6/docs/interceptors.html

SUMMARY:When you request a resource
that maps to an "action", the
framework invokes the Action object.
But, before the Action is executed,
the invocation can be intercepted by
another object. After the Action
executes, the invocation could be
intercepted again. Unsurprisingly, we
call these objects "Interceptors."

忆梦 2024-08-10 11:31:33

问题:如何判断视图是否已经生成?您是否设置请求标头或某种标志来确定视图是否已生成?

您可以尝试抛出 MemCachedException 来指示是时候加载到内存缓存中了。你的拦截器代码可以读取

try {
   return invocation.invoke();
} catch (MemCachedException mce) {
   // Your code to upload to MemCache.
} finally {
  // blah blah clean up.
}

Question: How do you determine if the view has been generated? Do you set a request header or an some sort of a flag to determine if the view has been generated?

You could try throwing a MemCachedException to indicate that it is time to load into a mem cache. Your interceptor code could read

try {
   return invocation.invoke();
} catch (MemCachedException mce) {
   // Your code to upload to MemCache.
} finally {
  // blah blah clean up.
}
dawn曙光 2024-08-10 11:31:33

在拦截器的 intercept() 方法中,ActionIn Vocation 参数有一个 getResult() 方法,该方法在 Action 之前返回 null执行(即在您的 intercept() 方法中调用 invocation.invoke() 之前),并在之后包含 Result 的实现。该对象应该为您提供某种方式来访问所需的数据,但如何完成这可能取决于实际使用的类。

另请参阅我的一些相关问题以及我在弄清楚后发布的答案。

Within your interceptor's intercept() method, the ActionInvocation parameter has a getResult() method which returns null before Action execution (i. e. before you call invocation.invoke() in your intercept() method) and contains an implementation of Result afterwards. That object should give you some way to access the data you need, but how this is done probably depends on the class that is actually used.

See also my somewhat related question and the answer I posted after figuring it out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文