Harry said:
I was wondering if anyone had implemented some sort of filter that
could alter the generated contents of a JSP. What I want to do is
grab the the results of a jsp before it is sent back to the client so
that I can add something to the dom tree. Is this possible?
Thanks,
Harry.
Yes, it will be painful but you should be able to achieve this.
I would suggest following approach (which I have not tried of course
since it is painful).
* Create a proxy implementation of HttpServletResponse interface which
should delegate all method invocations to the underlying
HttpServletResponse object provided by the container. You can write this
using a brute force approach or use java's proxying capability (see
java.lang.reflet.Proxy).
class ProxyHttpServletResponse implements HttpServletResponse
{
private HttpServletResponse proxiedObject ;
// some buffer ..
private ServletOutputStream buffer= new MyServletOutputStream(...) ;
private PrintWriter writer ;
ProxyHttpServletResponse (HttpServletResponse proxiedObject)
{
this.proxiedObject = proxiedObject ;
// You will have to do a better job with encoding!
this.writer = new ......(create using the buffer)
}
public void addCookie(Cookie cookie)
{
this.proxiedObject.addCookie(cookie) ;
}
...
...
}
* Change the implementation of getOutputStream and getWriter methods in
your proxy to return a stream/writer that keeps all the written content
in memory (or cache, file etc. ) and does not send it out.
public PrintWriter getWriter( )
{
return this.writer ;
}
public ServletOutputStream getOutputStream()
{
return buffer;
}
* Make sure you do the appropriate things with methods like
"flushBuffer", "reset" and "resetBuffer" . There may be more
stream/writer handling methods in HttpServletResponse interface.
* When forwarding call from the filter (doFilter method), create a new
HttpServletRequest object using your implementation and use your
implementation in place of container provided object.
doFilter(... )
{
//check and ensure that the types are all OK ..
ProxyHttpServletResponse bufferedResponse = new
ProxyHttpServletResponse ((HttpServletResponse) response) ;
filterChain.doFilter(... , bufferedResponse,...) ;
bufferedResponse.processJSPOutputAndFlush() ;
}
* Finally when the control gets back to you in the filter, you may want
to signal (send a message to) your proxy (servlet response object) to
manipulate the buffered output. Then write the contents to the proxied
HttpServletResponse object that was provided by the container.
void processJSPOutputAndFlush()
{
//do the processing ...
// write the contents to the original HttpServletResponse
objects stream and flush ..
}