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

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

问题描述

有什么办法可以在服务器端捕获生成的动态内容,并将相同的文件或字符串对象提供给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 请求是),那么你需要创建一个 过滤 包装 ServletResponse ,并自定义实现 PrintWriter ,其中包含五个 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();

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

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来区分这些请求。模式或以其他方式将其存储在会话中,例如在地图< URL,CopyWriter> 左右的味道。

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天全站免登陆