RE: filter questions

2002-01-09 Thread Cox, Charlie


  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.
 

that's good...it keeps it simple and we like simple :)

  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();
   ...

yes, that's what I meant. The getPathInfo() always returned null in my
filter. As I revisit the docs on getPathInfo():

a String, decoded by the web container, specifying extra path information
that comes after the servlet path but before the query string in the request
URL; or null if the URL does not have any extra path information

To me this should always return the filename requested. The file that my
filter is wrapping is actually handled by the DefaultServlet, not my own
servlet. In this case should getPathInfo() be returning the filename(or the
same as getRequetsURI())? I think it should as the servlet path should be
null, but I've never really dealt with the default servlet other than to let
it do its thing.

I worked around this by using getRequestURI().

 
 }
 
 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.
 

I used instanceOf just in case :)

  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.

I'm also using filters to enforce login(jdbcrealm doesn't agree with my jdbc
driver and I haven't taken the time to extend it to fix the problem) and
agreement to terms/conditions before receiving a file on the filesystem
through the DefaultServlet. Before using filters, I was manually reading the
file and serving it from my servlet to get this functionality which was
painful and I didn't support all the features(Range requests) which Tomcat
does through the defaulservlet. 
All it took was one instance of a download manager blowing up my servlet for
me to look for a better solution :) 

Charlie

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




Re: filter questions

2002-01-08 Thread Craig R. McClanahan



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]