操作 .html 和 .jsp 页面的响应主体

manipulate the response body of .html and .jsp page

所以我使用这段代码获取了.jsp页面
的响应正文(访问页面的源代码) 有人可以帮助我如何提取 .html 页面的响应正文。

public class DetailFilter implements Filter {
    private FilterConfig config;
    public DetailFilter() {
        super();
    }

    public void init(final FilterConfig filterConfig) throws ServletException {
        this.config = filterConfig;
    }


    public void destroy() {
        config = null;
    }

    public void doFilter(final ServletRequest request, final ServletResponse response,
                         final FilterChain chain) throws IOException, ServletException {

        ServletResponse newResponse = response;

        if (request instanceof HttpServletRequest) {
            newResponse = new CharResponseWrapper((HttpServletResponse) response);
        }

        chain.doFilter(request, newResponse);

        if (newResponse instanceof CharResponseWrapper) {
            String text = newResponse.toString();

            if (text != null) {
                response.getWriter().write(text);
                System.out.println("text is: "+text);
            }
        }
    }
}


public class CharResponseWrapper extends HttpServletResponseWrapper{
    protected CharArrayWriter charWriter;

    protected PrintWriter writer;

    protected boolean getOutputStreamCalled;

    protected boolean getWriterCalled;

    public CharResponseWrapper(HttpServletResponse response) {
        super(response);

        charWriter = new CharArrayWriter();
    }

    public ServletOutputStream getOutputStream() throws IOException {
        if (getWriterCalled) {
            throw new IllegalStateException("getWriter already called");
        }

        getOutputStreamCalled = true;
        return super.getOutputStream();
    }

    public PrintWriter getWriter() throws IOException {
        if (writer != null) {
            return writer;
        }
        if (getOutputStreamCalled) {
            throw new IllegalStateException("getOutputStream already called");
        }
        getWriterCalled = true;
        writer = new PrintWriter(charWriter);

        return writer;
    }

    public String toString() {
        String s = null;
        if (writer != null) {
            s = charWriter.toString();
        }
        System.out.println("tosting is:"+s);
        return s;
    }
}

问题是 .jsp 页面的 getWriter() 方法(在 CharResponseWrapper 中)被调用并在编写器中返回值,但是 .html 页面的 ServletOutputStream 被调用并且它 returns空值。

我也同样尝试了 URLConnection 和 InputStreamReader。下面提到了我使用的代码

HttpServletRequest hReq = (HttpServletRequest) request;
StringBuffer ss=hReq.getRequestURL();
String u=ss.toString();
URL url = new URL(u);
URLConnection con = url.openConnection();
System.out.println("Connection successful");
InputStream is =con.getInputStream();
System.out.println("InputStream Successful");
BufferedReader br = new BufferedReader(new InputStreamReader(is));

String line = null;
String[] arr={};
while ((line = br.readLine()) != null) {
    System.out.println(line);
}

代码运行良好,并在控制台上打印 "Connection successful",但随后它继续无限循环,从未真正执行 "InputStream Successful"。 据我了解,一旦在我们调用 InputStream 时创建了连接,它就会向同一个 url 发送请求,并且整个过程会一次又一次地重复。可能这个过程只适用于特定的 url 例如 url="www.abcd.com"

我想提取 .html 页面的响应正文以进行一些数据操作。对此请提供任何帮助。

编辑

要继续这个问题,在我得到响应正文之后。我在标签前插入 JS。当我 SOP 该字符串时,我看到插入的响应正文。直到这一步都是 fine.I 将其转换为字节数组并将字节数组写入 servletoutputstream 实例。

ServletOutputStream newResponse1= response.getOutputStream();
newResponse1.write(bArray);
newResponse1.close();

其中bArray为插入JS的响应体,字节数组格式。 响应是 ServletResponse。 我得到的输出很奇怪。 JSP 页面被执行了两次。意味着如果我在 jsp 页面上有一个按钮,它会显示同一个按钮两次并执行 JS。 HTML 页面执行一次,但最终响应与我写的响应不同。表示我写的 bArray 数据(注入数据)与我在浏览器上看到的响应不同。

我觉得我需要再次覆盖 getOutputStream 方法,不幸的是我无法做到。请帮忙。 如果问题不清楚,请回复。

我也参考了

您需要拦截 传递给底层 ServletOutputStream 的输出,方法与 CharArrayWriter 相同。所以,我建议大家修改getOutputStream方法,将返回的对象封装到自己的ServletOutputStream实例中,作为CharResponseWrapper的实例变量存储(与CharArrayWriter相同)。像这样就够了:

public class MyServletOutputStream extends ServletOutputStream
{
    private final ServletOutputStream src;

    private final StringBuilder stb=new StringBuilder(4096);

    public MyServletOutputStream(ServletOutputStream src)
    {
        super();
        this.src=src;
    }

    @Override
    public void write(int b)
        throws IOException
    {
        this.src.write(b);
        this.stb.append((char)b);
    }

    public StringBuilder getStb()
    {
        return this.stb;
    }
}

最后,修改 toString 方法来决定它必须从哪个对象获取数据:CharArrayWriter 或 MyServletOutputStream。