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 / June 2006

Tip: Looking for answers? Try searching our database.

servlet filter buffer question

Thread view: 
Steve - 04 Jun 2006 14:43 GMT
I have a filter that I wrote to scoop the output of a JSP and save it to
a file.  It worked fine in Tomcat 4.x, but in Tomcat 5.5 it gives me
nothing for a small amount of output, and for a large amount of output I
get some content, but it is cut off at some point.  So it seems like
there is an issue with the buffer

I've tried setting the JSP page's buffer and autoflush to various
combinations, with no success, and have tried calling setBufferSize in
the response wrapper before calling doFilter, also to no avail.

Is there a Tomcat setting I need to monkey with perhaps?  Or something
in my JSP or Java code?
Matt Humphrey - 04 Jun 2006 16:43 GMT
>I have a filter that I wrote to scoop the output of a JSP and save it to a
>file.  It worked fine in Tomcat 4.x, but in Tomcat 5.5 it gives me nothing
[quoted text clipped - 8 lines]
> Is there a Tomcat setting I need to monkey with perhaps?  Or something in
> my JSP or Java code?

If the JSP page regularly appears correctly in a browser, the problem will
probably be in your code. Show us the code for reading the output and
writing the file.  You may not be reading all the output or closing the file
properly.

Cheers,
Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/
Steve - 04 Jun 2006 17:19 GMT
>> I have a filter that I wrote to scoop the output of a JSP and save it to a
>> file.  It worked fine in Tomcat 4.x, but in Tomcat 5.5 it gives me nothing
[quoted text clipped - 16 lines]
> Cheers,
> Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/

Here it is:

package filtertest;

import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class PrePostFilterMain extends GenericFilter {

  public void doFilter(final ServletRequest request,
                       final ServletResponse response,
                       FilterChain chain)
              throws IOException, ServletException {
    OutputStream out = response.getOutputStream();
    GenericResponseWrapper wrapper =
      new GenericResponseWrapper((HttpServletResponse) response);

    wrapper.setBufferSize(16384);
    chain.doFilter(request, wrapper);

    // look up file name that matches the original request URL
    String filename = null;

    String requestedPage = ((HttpServletRequest) request).getServletPath();
    requestedPage =
requestedPage.substring(requestedPage.lastIndexOf('/') + 1);
    ServletContext sc = getFilterConfig().getServletContext();
    if (sc == null)
      throw new javax.servlet.ServletException("Servlet context missing");

    filename = sc.getInitParameter(requestedPage + ".file");
    if (filename == null)
      throw new javax.servlet.ServletException("lookup of property \"" +
                                               requestedPage + ".file\"
failed");

    byte[] data = wrapper.getData();
    createFile(data, filename);
    out.write(("<hr>PrePostFilterMain output sent to file: " + filename
+ ": " +
            data.length + "/" + wrapper.getContentLength() + "
bytes<hr>").getBytes());
    out.write(data);
    out.write("<hr>FilterTest Post<hr>".getBytes());
    out.flush();
    out.close();
  }

  public void createFile(byte[] data, String filename)
            throws IOException {
    ServletContext sc = getFilterConfig().getServletContext();
    String path = sc.getRealPath(filename);
    FileOutputStream fos = new FileOutputStream(path);
    fos.write(data);
    fos.flush();
    fos.close();
  }

}
//------------------------------------------------------------

package filtertest;

import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class GenericFilter implements javax.servlet.Filter {

  private FilterConfig fc;

  public GenericFilter() { }

  public void doFilter(final ServletRequest request,
                       final ServletResponse response,
                       FilterChain chain)
         throws java.io.IOException, javax.servlet.ServletException {

    chain.doFilter(request, response);
  }

  public FilterConfig getFilterConfig() {
    return fc;
  }

  public void init(FilterConfig fc) {
    this.fc = fc;
  }

  public void destroy() {
    this.fc = null;
  }
}

//--------------------------------------------------------------------

package filtertest;

import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class GenericResponseWrapper extends HttpServletResponseWrapper {

  private ByteArrayOutputStream output;
  private int contentLength;
  private String contentType;

  public GenericResponseWrapper(HttpServletResponse response) {
    super(response);
    output = new ByteArrayOutputStream();
  }

  public ServletOutputStream getOutputStream() {
    return new FilterServletOutputStream(output);
  }

  public byte[] getData() {
    return output.toByteArray();
  }

  public PrintWriter getWriter() {
    return new PrintWriter(getOutputStream(), true);
  }

  public void setContentType(String type) {
    this.contentType = type;
    super.setContentType(type);
  }

  public String getContentType() {
    return this.contentType;
  }

  public int getContentLength()    {
    return contentLength;
  }

  public void setContentLength(int length) {
    this.contentLength = length;
    super.setContentLength(length);
  }

}
Matt Humphrey - 05 Jun 2006 15:31 GMT
>>> I have a filter that I wrote to scoop the output of a JSP and save it to
>>> a file.  It worked fine in Tomcat 4.x, but in Tomcat 5.5 it gives me
[quoted text clipped - 20 lines]
>
> package filtertest;

<code snip>

I've looked this over several times now and I'm not seeing anything that
looks suspicious.  Your buffer handling looks correct.  There's an
assumption at one point that the bytes retreived from the JSP page encode
characters the same was as the filter does for output, but I would expect
that to be the case anyway.  And similarly that the wrapping HTML that you
convert to bytes with .getBytes () will use the same encoding as the
content.  For these you  might want to use the getBytes("encoding") to be
explicit, but I'm not confident that that's the problem.

It almost looks like chain.doFilter is not waiting for the entire response.
What function does the filter chain do here?

Cheers,
Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/ 
Steve - 11 Jun 2006 16:11 GMT
>>>> I have a filter that I wrote to scoop the output of a JSP and save it to
>>>> a file.  It worked fine in Tomcat 4.x, but in Tomcat 5.5 it gives me
[quoted text clipped - 36 lines]
> Cheers,
> Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/ 

I had iso-8859-1, but tried switching to UTF-8 to no avail.

It seems that the buffer is empty unless it is full -- i.e., it doesn't
work if the data written is less than the buffer size.  If I have more
content than the buffer size, then I get content of exactly the size of
the buffer.  If I have less content, then I get nothing.  (You can see
my code where I report the array length and the getContentLength() value
-- for a small amount of content it says 0/0)

So I suppose I could try to read the size of the content written to the
output buffer at the end of the JSP and then pad it out to the full
length of the buffer, but that seems like an incredible kludge.
Steve - 11 Jun 2006 16:44 GMT
>>>>> I have a filter that I wrote to scoop the output of a JSP and save
>>>>> it to a file.  It worked fine in Tomcat 4.x, but in Tomcat 5.5 it
[quoted text clipped - 50 lines]
> output buffer at the end of the JSP and then pad it out to the full
> length of the buffer, but that seems like an incredible kludge.

An update -- it seems like dynamically padding isn't possible -- I don't
see any way to read the size of the written content.  But, If I pad the
end of the page with 8192-plus spaces, it "works".  So it seems to be
ignoring my buffer size request in the JSP and doing it in 8kb chunks.
If I force the last real content to fill a chunk, that gets written, and
the content gets cut off somewhere in the middle of my padding.

BTW, I'm not sure if I understand your question "What function does the
filter chain do here?"  If you mean what is the application, I'm sending
a dynamic page and saving a copy of what was sent.
Matt Humphrey - 12 Jun 2006 19:47 GMT
> An update -- it seems like dynamically padding isn't possible -- I don't
> see any way to read the size of the written content.  But, If I pad the
> end of the page with 8192-plus spaces, it "works".  So it seems to be
> ignoring my buffer size request in the JSP and doing it in 8kb chunks. If
> I force the last real content to fill a chunk, that gets written, and the
> content gets cut off somewhere in the middle of my padding.

The content-length header isn't always correct because it's sent before the
actual content is sent.. I'm thinking that Tomcat 4.x did the right thing
and looked at the actual size of the content, whereas 5.5 is looking at the
declared buffer size or the content header
> BTW, I'm not sure if I understand your question "What function does the
> filter chain do here?"  If you mean what is the application, I'm sending a
> dynamic page and saving a copy of what was sent.

I was just wondering if the filter chain could be interfering with the read
/ write operation--I'm unfamiliar with them. I can't think of anything else
and I'm too unfamiliar with the nuances of Tomcat.

Good luck,
Matt Humphrey matth@ivizNOSPAM.com  http://www.iviz.com/


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.