在服务器端捕获生成的动态内容 [英] Capture generated dynamic content at server side

查看:28
本文介绍了在服务器端捕获生成的动态内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以在服务器端捕获生成的动态内容并将该文件或字符串对象获取到 servlet.

Is there any way with which I can capture generated dynamic content on the server side and get that file or string object of the same to the servlet.

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

We can generate dynamic content with JSPs, but we dont have access to the generated dynamic content at the server side. As soon as we do the forward container generates the dynamic content and sends it to response.

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

I need access to generated dynamic content on the server side.

任何帮助将不胜感激.

推荐答案

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

If the request is idempotent (such as GET requests are), then just use java.net.URL to get an InputStream of the JSP output. E.g.

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

如果请求不是幂等的(比如POST请求是),那么你需要创建一个Filter 其中 包装 ServletResponsePrintWriter 与五个 write() 方法已被覆盖,其中您将输出复制到某个缓冲区/构建器中,该缓冲区/生成器存储在会话中或本地磁盘文件系统的临时文件夹中,以便之后可以在后续请求中访问.例如

If the request is not idempotent (such as POST requests are), then you need to create a Filter which wraps the ServletResponse with a custom implementation of the PrintWriter with the five write() methods been overridden wherein you copy output into some buffer/builder which you store in the session or a temporary folder at local disk file system so that it can be accessed afterwards in the subsequent requests. E.g.

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:

You can access the final output in any servlet of the subsequent request (note that you cannot access it in any servlet of the current request, because it's already too late to do something with it) by just accessing the CopyWriter in the session:

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

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

Note that you should map this filter on an url-pattern covering the JSP pages of interest and thus not on /* or so, otherwise it would run on static files (css, js, images, etc) which are included in the same JSP as well.

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

Also note that multiple requests inside the same session would override each other, it's up to you to distinguish between those requests by using a proper url-pattern or another way of storing it in session, e.g. in flavor of a Map<URL, CopyWriter> or so.

希望这会有所帮助.

这篇关于在服务器端捕获生成的动态内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆