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 b) throws IOException { try { ServOutp.write(b); ByteOutp.write(b); } catch (Exception e) { System.out.println(e); } } public byte [] getRespByte() { return ByteOutp.toByteArray(); } } smime.p7s Description: S/MIME Cryptographic Signature
RE: Migrating from Tomcat404 to Tomcat5019. Problem with Filter
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 b) throws IOException { try { ServOutp.write(b); ByteOutp.write(b); } catch (Exception e) { System.out.println(e); } } public byte [] getRespByte() { return ByteOutp.toByteArray(); } } This e-mail, including any attachments, is a confidential business communication, and may contain information that is confidential, proprietary and/or privileged. This e-mail is intended only for the individual(s) to whom it is addressed, and may not be saved, copied, printed, disclosed or used by anyone else. If you are not the(an) intended recipient, please immediately delete this e-mail from your computer system and notify the sender. Thank you
Re: Migrating from Tomcat404 to Tomcat5019. Problem with Filter
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
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]