tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Garrett <ljag...@thinkpig.org>
Subject Re: What's the best way to meddle with a ServletOutputStream
Date Mon, 08 Oct 2001 17:10:46 GMT
I tried doing something like that:

public class FooterValve extends ValveBase {
  public void invoke(Request _req, Response _res,
    ValveContext _context) throws IOException, ServletException {
    String comment = "<!-- Hello World -->";
    OutputStream oldStream = _res.getStream();
    _res.setStream(new ServletOutputStreamWrapper());
    _context.invokeNext(_req, _res);
    byte [] content =
      ((ServletOutputStreamWrapper)_res.getStream()).getBytes();
    StringBuffer sb = new StringBuffer(content.length + comment.length);
    sb.append(new String(content, 0, content.length));
    sb.append(comment);
    oldStream.write(sb.toString().getBytes());
    _res.setStream(oldStream);
  }
}

And I get strange results. Sometimes the "Hello World" comment is at the
bottom, but more often it's either the first item sent -- before the
headers, even -- or it's stuck in a random point in the middle of the
page. E.g. from /index.html

     <li><b><a 
href="mailto:tomcat-user-subscribe@jakarta.apache.org">tomcat-user@jakarta.ap<!-- Hello
World -->ache.org</a></b> for general questions related to configuring and
using Tomcat</li>
           </ul>

Incidentally, the ServletOutputStreamWrapper I'm using is just a wrapper
around a ByteArrayOutputStream, essentially like the one in the util.ssi
package, but with a method for getting the byte array back.

Any ideas?

Thanks,
	Alex

On Mon, 2001-10-08 at 10:37, Craig R. McClanahan wrote:
> 
> 
> On Sun, 7 Oct 2001, Jeff Kean wrote:
> 
> > Date: Sun, 7 Oct 2001 22:17:27 -0500
> > From: Jeff Kean <jvkean@mc.net>
> > Reply-To: tomcat-dev@jakarta.apache.org
> > To: tomcat-dev@jakarta.apache.org
> > Subject: What's the best way to meddle with a ServletOutputStream
> >
> > I'm writing a valve that will automatically add headers and footers to
> > any web pages that Tomcat serves up. It seems to me that the way to do
> > this is to add a valve to one of the containers (say, the Engine level)
> > that replaces the ServletOutputStream in the response with a wrapper
> > around a ByteArrayOutputStream (similar to
> > ...util.ssi.ServletOutputStreamWrapper), let the servlet process the
> > request, yank the data out of the Wrapper, tweak it, and write it to the
> > original ServletOutputStream.
> >
> > Here are my questions:
> > 1) Is this the Right Way to do it?
> 
> Using a Valve would be the right approach if you want to do this inside of
> Tomcat.  Just be sure your SOS implementation implements all of the
> cooperative functionality (with ResponseBase) that is currently
> implemented.
> 
> However, for this particular requirement, you can also use the new Filter
> APIs in Servlet 2.3 to wrap the response that is passed on to the servlet
> or JSP page that is ultimately executed.  This has a decided advantage of
> being portable across all 2.3-compatible containers (instead of being
> specific to Tomcat).  There was a recent "Tech Tip" about doing this at
> <http://developer.java.sun.com>, which used a Filter to do an XSLT
> transformation on the output from a servlet.
> 
> > 2) If so, do I just do something like:
> >   OutputStream oldStream = response.getStream();
> >   response.setStream(new SOSWrapper()); // BAOS wrapper that extends SOS
> >   invoke(request, response);
> >   StringBuffer sb = new StringBuffer(response.getStream().getBytes());
> >   sb.append("<!-- Hello World! -->");
> >   oldStream.write(sb.toString());
> >   response.setStream(oldStream);
> >   // drop off edge
> >
> 
> That looks about right.
> 
> > Incidentally, part of the reason I'm curious about this is to increase my
> > understanding
> > of Tomcat, so please don't simply respond with "use JSSI".
> >
> > Thanks!
> >
> 
> Craig
> 


Mime
View raw message