On Tue, 8 Jan 2002, Cox, Charlie wrote:

> Date: Tue, 8 Jan 2002 16:16:44 -0500
> From: "Cox, Charlie" <[EMAIL PROTECTED]>
> Reply-To: Tomcat Users List <[EMAIL PROTECTED]>
> To: 'Tomcat Users List' <[EMAIL PROTECTED]>
> Subject: filter questions
>
> I have read in the spec and tried a filter myself, and I have a few
> questions:
>
> 1. Where the spec(pg 45) says:
> "Only one instance per filter declaration in the deployment descriptor is
> instantiated per Java virtual machine of the container."
> I read this as it works similar to a servlet, one instance per virtual
> host(not jvm) with many threads. Is this correct?
>

Yes, that's right.  The same thread safety issues apply.

> 2. I have a filter on a downloadable file(50MB) and I have noticed that when
> the user clicks 'cancel' on the browser, that it throws an IOException,
> which I can trap in my filter ['try' around doChain()]. If I rethrow this
> exception(after my processing), it is like I never touched it and it writes
> an error in the log about 'socket write error'. If I do not rethrow this
> exception is there any processing or cleanup, that will not get done
> correctly? Or can I just return without rethrowing? I would really like to
> cut down on the 'socket write errors' in the logs.
>

Again, the same principles apply here as would apply in the servlet that
creates the output in the first place.  You can indeed swallow the
exception, if you would do so in the servlet itself.

> 3. How can I check the status(200,404,etc) on the response object after the
> doChain() has returned? I don't need to wrap the request/response, I am just
> interested in knowing when a 404 occurs(only within this filter if
> possible). I tried converting it to a HttpServletResponse object, but I
> don't see how to *read* the status.
>

You *do* need a wrapper to make this information available - an example
might look like this:

  public class MyResponseWrapper extends HttpServletResponseWrapper {

    protected int saveStatus = 0;

    public MyResponseWrapper(HttpServletResponse response) {
      super(response);
    }

    // Override Servlet API methods to save the status value

    public void sendError(int sc) {
      saveStatus = sc;
      super.sendError(sc);
    }

    public void sendError(int sc, String message) {
      saveStatus = sc;
      super.sendError(sc, message);
    }

    // ... all the other HttpServletResponse methods are delegated
    // ... to the superclass automatically

    // Extra public method to retrieve the status value

    public int getStatus() {
      return (saveStatus);
    }

}

Then, after chain.doFilter() returns, you can call the getStatus() method
to see what the response status was:

    MyResponseWrapper wresponse =
      new MyResponseWrapper((HttpServletResponse) response);
    chain.doFilter(request, wresponse);
    int status = wresponse.getStatus();
    if (status == HttpServletResponse.SC_NOT_FOUND) {
      ...
    }

> 4. How much more efficient is handling a request in filter than handling it
> in a servlet if the handling code is the same. I noticed that when I
> converted the ServletRequest to an HttpServletRequest that not all the
> functions were available(getPathInfo() was the one that I noticed), so I
> assume that there is some processing going on between the filter and the
> servlet - but I could be wrong.
>

By "converted", you mean casting don't you?

    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
        throws IOException, ServletException {

      HttpServletRequest hrequest = (HttpServletRequest) request;
      String pathInfo = hrequest.getPathInfo();
      ...

    }

This will either work or throw a ClassCastException if the request isn't
really an HTTP one -- but that won't happen to you in a standard Tomcat
installation because they are all HTTP requests.

Filtering actually does impose a small performance penalty (minimally, an
extra method call for each request, plus whatever overhead it takes to set
up the filter chain), but IMHO it's very much worth it for the cleaner
code design that is enabled.

> I'm really liking these filters since I share servlets between virtual
> hosts, and now I see that filters can really help cleanup the customized
> processing in my servlets for each virtual host.
>

That's a pretty good use case.  The other thing I really like about
filters is that you can divide your processing into lots of little
filters, and then mix and match the ones you need for a particular
purpose.

> Charlie
>
> --
> To unsubscribe:   <mailto:[EMAIL PROTECTED]>
> For additional commands: <mailto:[EMAIL PROTECTED]>
> Troubles with the list: <mailto:[EMAIL PROTECTED]>
>
>


--
To unsubscribe:   <mailto:[EMAIL PROTECTED]>
For additional commands: <mailto:[EMAIL PROTECTED]>
Troubles with the list: <mailto:[EMAIL PROTECTED]>

Reply via email to