捕获服务器端生成的动态内容

时间:2009-12-26 11:08:57

标签: java jsp servlets

有什么办法可以在服务器端捕获生成的动态内容,并将相同的文件或字符串对象提供给servlet。

我们可以使用JSP生成动态内容,但是我们无法访问服务器端生成的动态内容。我们一旦转发容器生成动态内容并将其发送到响应。

我需要访问服务器端生成的动态内容。

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:15)

如果请求是幂等的(例如GET请求),则只需使用java.net.URL来获取JSP输出的InputStream。 E.g。

InputStream input = new URL("http://localhost/context/page.jsp").openStream();

如果请求不是幂等的(例如POST个请求),那么您需要创建一个Filter wraps ServletResponse write()的自定义实现已覆盖五个package mypackage; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.Writer; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class CopyResponseFilter implements Filter { public void init(FilterConfig config) throws ServletException { // NOOP. } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // Set character encoding for better world domination. response.setCharacterEncoding("UTF-8"); // Create copy writer. HttpServletResponse httpResponse = (HttpServletResponse) response; CopyWriter copyWriter = new CopyWriter(new OutputStreamWriter( httpResponse.getOutputStream(), httpResponse.getCharacterEncoding())); // Filter request with response which is wrapped with new writer. chain.doFilter(request, wrapResponse(httpResponse, copyWriter)); // Store the copy writer afterwards in session so that it's available in next request. HttpServletRequest httpRequest = (HttpServletRequest) request; httpRequest.getSession().setAttribute("copyWriter", copyWriter); } public void destroy() { // NOOP. } private static HttpServletResponse wrapResponse (final HttpServletResponse response, final PrintWriter writer) { return new HttpServletResponseWrapper(response) { public PrintWriter getWriter() throws IOException { return writer; } }; } } class CopyWriter extends PrintWriter { StringBuilder copy = new StringBuilder(); public CopyWriter(Writer out) { super(out); } public void write(int c) { copy.append((char) c); // It is actually a char, not an int. super.write(c); super.flush(); } public void write(char[] chars) { copy.append(chars); super.write(chars); super.flush(); } public void write(char[] chars, int offset, int length) { copy.append(chars, offset, length); super.write(chars, offset, length); super.flush(); } public void write(String string) { copy.append(string); super.write(string); super.flush(); } public void write(String string, int offset, int length) { copy.append(string, offset, length); super.write(string, offset, length); super.flush(); } public String getCopy() { return copy.toString(); } } 方法的PrintWriter,其中您将输出复制到存储在会话中的某个缓冲区/构建器或本地磁盘文件系统上的临时文件夹中,以便随后可以在后续访问要求。 E.g。

CopyWriter

您可以访问后续请求的任何servlet中的最终输出(请注意,不能当前请求的任何servlet中访问它,因为它已经太晚了只需访问会话中的CopyWriter copyWriter = (CopyWriter) request.getSession().getAttribute("copyWriter"); String outputOfPreviousRequest = copyWriter.getCopy();

,即可对其执行操作
url-pattern

请注意,您应该在覆盖感兴趣的JSP页面的/*上映射此过滤器,因此不会在url-pattern左右,否则它将在静态文件(css,js,images等)上运行)也包含在同一个JSP中。

另请注意,同一会话中的多个请求会相互覆盖,您可以通过使用正确的Map<URL, CopyWriter>或其他方式将其存储在会话中来区分这些请求,例如:在{{1}}左右的味道。

希望这有帮助。

答案 1 :(得分:2)

据我了解您的目标,您希望存储生成的内容。虽然我想不出任何理由这样做,但有可能。

您可以使用Filter并创建HttpServletResponse的包装,覆盖一些write方法并捕获将输出到浏览器的所有内容。

编辑:BalusC的回答是你需要的确切扩展,所以我不会详细介绍。

答案 2 :(得分:0)

您需要在服务器端访问相应的servlet,或者您可以编写servlet。

Here是一个关于使用servlet的小教程。

答案 3 :(得分:0)

需要注意的重要一点是,JSP通过JSP编译器编译为servlet(可能会在中途生成java代码),因此您可以在JSP中使用servlet执行任何操作。

关于这个主题的一个侧面说明:你应该知道MVC,一般来说servlet充当控制器,JSP充当View,任何数据结构(java bean等)充当模型。

对于您的问题,您应该在servlet中生成内容/数据 - 这是由对象表示的动态内容,执行您需要执行的任何处理,设置此数据以便JSP可以访问它(在{{3}中)例如),在JSP中为客户端访问和格式化它。

要熟悉,您应该查看request attributeStory of a Servlet: An Instant Tutorial