操纵.html和.jsp页面的响应体

时间:2015-07-23 17:50:58

标签: java html servlets inputstream bufferedinputstream

所以我使用这段代码来获取.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并返回null值。

我也尝试过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);
}

代码顺利,打印"连接成功"在控制台上,然后它继续作为一个无限循环,永远不会真正执行" InputStream成功"。 根据我的理解,一旦我们调用InputStream创建了连接,它就会向同一个url发送请求,并且会一次又一次地重复整个过程。可能此过程仅适用于特定网址,例如url =" www.abcd.com"

我想提取.html页面的响应主体以进行一些数据操作。这个PLZ的任何帮助。

修改

在我得到回复正文之后继续这个问题。我在标签之前插入JS。当我SOP那个字符串时,我看到插入的响应体。直到这一步一切都很好。我将它转换为字节数组并在servletoutputstream实例中写入字节数组。

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

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

我觉得我需要再次覆盖getOutputStream方法,遗憾的是我无法这样做。请帮忙。 如果问题不明确则恢复。

我也参考了How to read and copy the HTTP servlet response output stream content for logging

1 个答案:

答案 0 :(得分:0)

您需要拦截传递给基础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。