Re: Migrating from Tomcat404 to Tomcat5019. Problem with Filter

2004-04-16 Thread Alex Moots
Thank you to both Antonio and Yoav for your suggestions.

I tried implementing a flush() method.  It is only called once toward 
the end of the 3KB of data that are transmitted.  close() is never 
called.  That seems kinda odd, but maybe it is normal?

Yoav, could you suggest where I could look for more information on the 
underlying stream processor implementation changes?  Also, it 
shouldn't matter if the underlying implementation changes, if I write to 
the API (which I believe I am) then the underlying implementation should 
be changeable (I know, famous last words).  Do you by any chance have 
any alternative suggestions for what I'm trying to do?  That is, I'm 
trying to capture the exact output of a servlet request (.jsps in my 
case) so that I can do other processing on it (for example, save it to a 
file).

Thanks for you help
Alex.
Shapira, Yoav wrote:

Hi,
But I think the guesses are on the right path: it's definitely an IO problem.  I don't 
like an approach that's subject to breaking if the underlying stream processor 
implementation changes (as it did from tomcat 4 to 5).  Your 10KB/3KB approach 
suggests a buffering or chunking issue.  I have to run to a meeting though ;)
Yoav Shapira
Millennium Research Informatics
 

-Original Message-
From: Antonio Fiol BonnĂ­n [mailto:[EMAIL PROTECTED]
Sent: Friday, April 16, 2004 2:22 AM
To: Tomcat Users List
Subject: Re: Migrating from Tomcat404 to Tomcat5019. Problem with Filter
Two things I would double-check:

a) The approach of creating a PrintWriter at constructor time. Is that
the right way of doing that?
b) Think of implementing flush and/or close for your ServletOutputStream.
HTH (but these are mostly wild guesses)

Antonio Fiol

Alex Moots wrote:

   

I've been using a custom made servlet filter developed for Tomcat404.
It has worked perfectly for a long time.
The basic idea of the filter is that it acts as a wrapper around the
response filter capturing the response output so that the output can
be sent to a second destination (ie an email message body or something
similar).  We call this a Double Output Stream filter.  The code for
this filter is quite simple and I've attached a simplified version of
it below.  The whole thing is less than 70 lines of code.
The problem is that this filter doesn't work properly in Tomcat5019.
I don't get an exception during processing.  The problem is that the
respByte [] (which should contain the array of bytes sent to the
browser) is not populated, or is only partially populated.  And when
this filter is invoked only a partial page is sent to the browser.
For example, if my page is 10KB long only 3KB will be sent to the
browser, and similarly only 3KB will be present in the respByte
array.  It seems like what is happening is that Tomcat5019 is
short-circuiting the execution of the page for some reason.  I don't
know why.  The code worked fine in tomcat404 and I didn't change
anything during the upgrade to tomcat5019.
Can anyone give an idea of what is going wrong here?  I did some
searching to see if the servlet filter API changed between tomcat404
and 5019, but I didn't find anything to suggest that things have
changed significantly.
Thanks for your help.
Alex.
**CODE***

public class SaveAsHTMLFilter implements Filter {
  public void doFilter(ServletRequest request, ServletResponse
response, FilterChain chain) throws IOException, ServletException {
  //Re the real response in a DoubleResponseWrapper which
encloses the
  //real OutputStream, plus a ByteArrayOutputStream, into a
DoubleOutputStream
  DoubleResponseWrapper respWrap = new
DoubleResponseWrapper((HttpServletResponse) response);
  //Process the request to generate the output into the
respWrap's DoubleOutputStream
  chain.doFilter(request, respWrap);
  //retrieve the ByteArray
  byte respByte[] = respWrap.getRespByte();
  // [SNIP]
  // Send the respByte array (which is the response that was sent
to the browser) to an email message or something similar
  // [SNIP]
  }
}
***
public class DoubleResponseWrapper extends HttpServletResponseWrapper {
DoubleOutputStream dblOS;
PrintWriter pw;
public DoubleResponseWrapper(HttpServletResponse resp) throws
IOException {
  super(resp);
  ServletOutputStream servOutp  = resp.getOutputStream();
  ByteArrayOutputStream   byteArray = new ByteArrayOutputStream(32000);
  dblOS = new DoubleOutputStream(servOutp, byteArray);
  pw = new PrintWriter(dblOS);
}
public ServletOutputStream getOutputStream () throws IOException {
  return dblOS;
}
public PrintWriter getWriter() throws IOException {
  return pw;
}
public byte getRespByte()[] {
  return dblOS.getRespByte();
}
}
***
public class DoubleOutputStream extends ServletOutputStream {
private ServletOutputStream ServOutp;
private ByteArrayOutputStream ByteOutp;
public DoubleOutputStream(ServletOutputStream sos,
ByteArrayOutputStream bos) {
  ServOutp = sos;
  ByteOutp = bos;
}
public void write(int

Migrating from Tomcat404 to Tomcat5019. Problem with Filter

2004-04-15 Thread Alex Moots
I've been using a custom made servlet filter developed for Tomcat404.  
It has worked perfectly for a long time.

The basic idea of the filter is that it acts as a wrapper around the 
response filter capturing the response output so that the output can be 
sent to a second destination (ie an email message body or something 
similar).  We call this a Double Output Stream filter.  The code for 
this filter is quite simple and I've attached a simplified version of it 
below.  The whole thing is less than 70 lines of code.

The problem is that this filter doesn't work properly in Tomcat5019.  I 
don't get an exception during processing.  The problem is that the 
respByte [] (which should contain the array of bytes sent to the 
browser) is not populated, or is only partially populated.  And when 
this filter is invoked only a partial page is sent to the browser.  For 
example, if my page is 10KB long only 3KB will be sent to the browser, 
and similarly only 3KB will be present in the respByte array.  It seems 
like what is happening is that Tomcat5019 is short-circuiting the 
execution of the page for some reason.  I don't know why.  The code 
worked fine in tomcat404 and I didn't change anything during the upgrade 
to tomcat5019.

Can anyone give an idea of what is going wrong here?  I did some 
searching to see if the servlet filter API changed between tomcat404 and 
5019, but I didn't find anything to suggest that things have changed 
significantly.

Thanks for your help.
Alex.
**CODE***

public class SaveAsHTMLFilter implements Filter {
   public void doFilter(ServletRequest request, ServletResponse 
response, FilterChain chain) throws IOException, ServletException {
   //Re the real response in a DoubleResponseWrapper which encloses the
   //real OutputStream, plus a ByteArrayOutputStream, into a 
DoubleOutputStream
   DoubleResponseWrapper respWrap = new 
DoubleResponseWrapper((HttpServletResponse) response);

   //Process the request to generate the output into the respWrap's 
DoubleOutputStream
   chain.doFilter(request, respWrap);

   //retrieve the ByteArray
   byte respByte[] = respWrap.getRespByte();
   // [SNIP]
   // Send the respByte array (which is the response that was sent 
to the browser) to an email message or something similar
   // [SNIP]
   }
}

***
public class DoubleResponseWrapper extends HttpServletResponseWrapper {
DoubleOutputStream dblOS;
PrintWriter pw;
 public DoubleResponseWrapper(HttpServletResponse resp) throws 
IOException {
   super(resp);
   ServletOutputStream servOutp  = resp.getOutputStream();
   ByteArrayOutputStream   byteArray = new ByteArrayOutputStream(32000);
   dblOS = new DoubleOutputStream(servOutp, byteArray);
   pw = new PrintWriter(dblOS);
 }
 public ServletOutputStream getOutputStream () throws IOException {
   return dblOS;
 }
 public PrintWriter getWriter() throws IOException {
   return pw;
 }
 public byte getRespByte()[] {
   return dblOS.getRespByte();
 }
}

***
public class DoubleOutputStream extends ServletOutputStream {
 private ServletOutputStream ServOutp;
 private ByteArrayOutputStream ByteOutp;
 public DoubleOutputStream(ServletOutputStream sos, 
ByteArrayOutputStream bos) {
   ServOutp = sos;
   ByteOutp = bos;
 }

 public void write(int b) throws IOException {
   try {
   ServOutp.write(b);
   ByteOutp.write(b);
 } catch (Exception e) {
 System.out.println(e);
 }
 }
 public byte [] getRespByte() {
   return ByteOutp.toByteArray();
 }
}
-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]