【发布时间】:2009-08-23 04:33:10
【问题描述】:
我想知道是否可以在结果返回并呈现 JSP 后捕获操作的结果。我希望能够获取整个结果(生成的 HTML)并将其推送到 memcached 中,这样我就可以通过 Nginx 带来它而无需访问应用程序服务器。有什么想法吗?
PS:我知道我可以在动作执行之后但在结果返回和呈现 JSP 之前运行拦截器,但不能在呈现 JSP 之后运行。
【问题讨论】:
标签: struts2 memcached interceptor
我想知道是否可以在结果返回并呈现 JSP 后捕获操作的结果。我希望能够获取整个结果(生成的 HTML)并将其推送到 memcached 中,这样我就可以通过 Nginx 带来它而无需访问应用程序服务器。有什么想法吗?
PS:我知道我可以在动作执行之后但在结果返回和呈现 JSP 之前运行拦截器,但不能在呈现 JSP 之后运行。
【问题讨论】:
标签: struts2 memcached interceptor
我还没有找到在 struts2 中执行此操作的方法,最好创建一个 servlet 过滤器并让它修改 OutputStream。
【讨论】:
嘿,我知道现在回答已经很晚了,您可能已经找到了答案,但是为了其他人受益,我发布了答案。
与您正在做的事情非常相似的一件事是通过 sitemesh 过滤器完成的。
是的,过滤器出现在 Struts2 过滤器本身之前和之后,因此您可以轻松地弄乱输入和输出。
但是 struts 确实会评估 JSP/freemarker/velocity 并生成传递给用户的最终 html。 JSP 有点棘手,因为在内部调用了一个 servlet,但是查看org.apache.struts2.views.freemarker.FreemarkerResult class,您可以看到在template.process(model, writer); 中生成了实际的 html。这个作者其实是ServletActionContext.getResponse().getWriter();
现在要获取 html,您需要做的就是
ServletActionContext.getResponse().getWriter().toString() //This does not work out of box。要让 toString() 工作,您需要使用 ResponseWrapper - 这与在过滤器中获取结果 html 的方法相同。见-Programming Customized Requests and Responses。
在 struts 2 中修改生成的 html 的列表。这未经测试,但它是从我之前为自定义模板引擎编写的代码中提取的。我可能会在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
}
}
【讨论】:
阅读这篇文章 - http://struts.apache.org/2.0.6/docs/interceptors.html
摘要:当您请求资源时 映射到一个“动作”, 框架调用 Action 对象。 但是,在执行 Action 之前, 调用可以被拦截 另一个对象。行动后 执行,调用可能是 再次被拦截。不出所料,我们 将这些对象称为“拦截器”。
【讨论】:
问题:如何确定视图是否已生成?您是否设置了请求标头或某种标志来确定是否已生成视图?
您可以尝试抛出 MemCachedException 来指示是时候加载到内存缓存中了。您的拦截器代码可以读取
try {
return invocation.invoke();
} catch (MemCachedException mce) {
// Your code to upload to MemCache.
} finally {
// blah blah clean up.
}
【讨论】:
在您的拦截器的intercept() 方法中,ActionInvocation 参数有一个getResult() 方法,该方法在Action 执行之前(即在您在intercept() 方法中调用invocation.invoke() 之前)返回null,并包含一个实现Result 之后。该对象应该为您提供一些访问所需数据的方法,但如何完成可能取决于实际使用的类。
另请参阅my somewhat related question 以及我在弄清楚后发布的答案。
【讨论】: