Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / December 2005

Tip: Looking for answers? Try searching our database.

Using a servlet filter to modify output of a jsp?

Thread view: 
Harry Bosch - 01 Dec 2005 18:32 GMT
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.
Oliver Wong - 01 Dec 2005 20:44 GMT
>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
kiranmalla.in@gmail.com - 01 Dec 2005 21:06 GMT
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
Abhijat Vatsyayan - 01 Dec 2005 22:52 GMT
> 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
[quoted text clipped - 4 lines]
>
> 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 ..
    }
Harry Bosch - 06 Dec 2005 14:31 GMT
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 - 06 Dec 2005 18:20 GMT
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.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.