Using a servlet filter to modify output of a jsp?

Discussion in 'Java' started by Harry Bosch, Dec 1, 2005.

  1. Harry Bosch

    Harry Bosch Guest

    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.
    Harry Bosch, Dec 1, 2005
    #1
    1. Advertising

  2. Harry Bosch

    Oliver Wong Guest

    "Harry Bosch" <> wrote in message
    news:...
    >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?


    Yes.

    One simple way to do it is to have the your code fetch the JSP as if it
    were a web browser, connecting via HTTP to the local loopbrack address and
    everything, and then do whatever modifications you want, and then send that
    to the user.

    It's sort of like writing a proxy.

    - Oliver
    Oliver Wong, Dec 1, 2005
    #2
    1. Advertising

  3. Harry Bosch

    Guest

    Hi Harry

    I think this should be perfectly possible. Haven't tried it though. You
    can implement a filter to do such type of stuff. I have implemented a
    filter which gives me log information about when the modeler (can be
    used to provide the info abt jsp as well) is executed.

    A filter would provide you callback methods which you can use to alter
    request or response object. So i would assume you want to add some
    attribute to the response object before serving it to the client which
    should be perfectly possible using a filter. I have used filter to
    explicitly set the character encoding to UTF-8 before serving the
    response..

    Hope this helps!

    -Kiran
    , Dec 1, 2005
    #3
  4. Harry Bosch wrote:
    > 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 ..
    }
    Abhijat Vatsyayan, Dec 1, 2005
    #4
  5. Harry Bosch

    Harry Bosch Guest

    Thanks for the reply Abhijat (and everyone else), I think I will go
    with your solution. I'll start coding now and see how it goes. FYI,
    the reason I am doing this is so I can set up environments for
    development, testing, integeration (and production, but this will be
    disabled there) and have the contents of the returned HTML altered
    based on those configurations. Doing this allows up to have a simple
    environment variable set and have the page altered based on that
    variable so that developers/testers etc. know which environment they
    are working on. This way I don't have to have every page, or what-not,
    contain code for this environment aware feature. Hope that explains
    it.

    If anyone has tackled this issue more easily, let me know. Perhaps I
    am making this a bit too complicated, but when it's running, it seems
    like it could work nicely. Though, a bit of processing, but that is
    only in the non-production environments.
    Harry Bosch, Dec 6, 2005
    #5
  6. Harry Bosch

    Harry Bosch Guest

    After looking through the API docs I did find a convenient decorator
    for wrapping a servlet response:
    javax.servlet.http.HttpServletResponseWrapper. This way I only need to
    override a couple methods to handle what I needed to do. It's
    basically the pattern that you, Abhijat, were pointing me at. I was
    going the actual java.lang.reflect.Proxy route but I came across this
    and figured I would just "get it over with".

    Thanks again.
    Harry Bosch, Dec 6, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. javaguy44
    Replies:
    0
    Views:
    2,643
    javaguy44
    Apr 1, 2004
  2. circuit_breaker
    Replies:
    2
    Views:
    1,983
    Jack Jia
    Apr 4, 2004
  3. javadev
    Replies:
    5
    Views:
    12,860
    javadev
    Nov 16, 2006
  4. Replies:
    4
    Views:
    768
  5. Mav
    Replies:
    22
    Views:
    355
Loading...

Share This Page