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

标签 java jsp servlets

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

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

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

我们将不胜感激。

最佳答案

如果请求是幂等的(比如GET请求是),那么就使用 java.net.URL 获取 JSP 输出的 InputStream。例如

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

如果请求不是幂等的(比如POST请求是),那么你需要创建一个 Filter 哪个wraps ServletResponse使用 PrintWriter 的自定义实现与五个write()方法被覆盖,其中您将输出复制到您存储在 session 中的某个缓冲区/构建器或本地磁盘文件系统中的临时文件夹中,以便以后可以在后续请求中访问它。例如

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();
    }

}

您可以在后续请求的任何 servlet 中访问最终输出(请注意,您不能当前请求的任何 servlet 中访问它,因为已经太晚了用它做点什么)只需访问 CopyWriter在 session 中:

CopyWriter copyWriter = (CopyWriter) request.getSession().getAttribute("copyWriter");
String outputOfPreviousRequest = copyWriter.getCopy();

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

另请注意,同一 session 中的多个请求会相互覆盖,您可以使用适当的 url-pattern 来区分这些请求。或另一种将其存储在 session 中的方式,例如味道 Map<URL, CopyWriter>左右。

希望这对您有所帮助。

关于java - 在服务器端捕获生成的动态内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1963158/

相关文章:

java - 如何使用<h :commandButton action ="#{method here}"/>?

java - 调用servlet将JSON格式的数据写入服务器中的URL

java - 如何正确使用StringBuffer#insert?

java - session 劫持: Pros/Cons of a filter that suppresses Session IDs

java - FirebaseInitProvider。找不到资源

java - 使用jquery在jsp页面中接受http session 请求参数

java - WSO2 身份服务器管理控制台显示没有 STS 链接

java - 如何访问Struts标签中的迭代器变量?

java - 表单向 Servlet 发送空查询字符串

java - 在 servlet 中使用 PDFParser 时未找到类定义。但在Java应用程序中工作