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

Vis*_*ath 13 java jsp servlets

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

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

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

任何帮助将不胜感激.

Bal*_*usC 15

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

InputStream input = new URL("http://localhost/context/page.jsp").openStream();
Run Code Online (Sandbox Code Playgroud)

如果请求不是幂等(如POST请求是),那么你需要创建一个Filter包装ServletResponse一个自定义实施PrintWriter的五个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();
    }

}
Run Code Online (Sandbox Code Playgroud)

您可以访问后续请求的任何servlet中的最终输出(请注意,您无法通过访问会话中的当前请求的任何servlet访问它,因为已经为时已晚,无法使用它)CopyWriter:

CopyWriter copyWriter = (CopyWriter) request.getSession().getAttribute("copyWriter");
String outputOfPreviousRequest = copyWriter.getCopy();
Run Code Online (Sandbox Code Playgroud)

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

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

希望这可以帮助.