tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <craig...@apache.org>
Subject Re: Where can I find the .sendRedirect source code?
Date Wed, 14 Nov 2001 17:35:53 GMT


On Wed, 14 Nov 2001, Carl Boudreau wrote:

> Date: Wed, 14 Nov 2001 09:37:37 -0600
> From: Carl Boudreau <carl.boudreau@notiva.com>
> Reply-To: Tomcat Users List <tomcat-user@jakarta.apache.org>,
>      carl.boudreau@notiva.com
> To: 'Tomcat Users List' <tomcat-user@jakarta.apache.org>
> Subject: Where can I find the .sendRedirect source code?
>
> Hi,
>
> Can anyone point me to the area where the redirect are handled in tomcat?
> I have already downloaded the source, but can't find the exact location.
>

In Tomcat 4, it's in class org.apache.catalina.connector.HttpResponseBase.

Basically, sendRedirect() does the following:
* Sets the response status to 302 (moved temporarily)
* Adds a "Location" header whose value is the absolute URL
  to which the browser is being redirected.

One of the most common problems you might be encountering is trying to do
this after the response has been committed.  Because the HTTP status and
headers are sent at the beginning of a response, any attempt to modify
them after the first part of the response has been written will fail with
an IllegalStateException.

A second common problem is trying to do a sendRedirect() from inside a
servlet or JSP page that is included via a request dispatcher.  It's not
legal for an included resource to modify the headers, so this would get
ignored.

> And how about any flow diagrams that shows how tomcat is put together,
> what classes are being called and the basic flow of the application?
>

Alas there is not -- I've been eagerly waiting for ArgoUML to finish
implementing sequence diagrams so I can draw some nice ones :-).  It's
almost there ...

In the mean time, the flow of a request goes basically like this in Tomcat
4 standalone ("o.a.c." is short for "org.apache.catalina."):

* o.a.c.connector.http.HttpConnector has a server socket
  waiting for connects.  It receives the incoming connect
  and passes it on to an HttpProcessor (on a different thread).

* o.a.c.connector.http.HttpProcessor converts the incoming
  headers into an instance of o.a.c.HttpRequst, and also creates
  an instance of o.a.c.HttpResponse.

* The processor then calls invoke() on the o.a.c.Container
  associated with our Service.  In the usual configuration, this
  will be the <Engine> you have configured in server.xml -- an
  instance of o.a.c.core.StandardEngine.

* o.a.c.core.StandardEngine passes the request and response through
  any Valves that you have configured inside the <Engine> element.
  The last of these will be o.a.c.core.StandardEngineValve, which
  figures out which host should handle the request and passes it on
  to the Host's invoke() method.

* o.a.c.core.StandardHost passes the request and response through
  any Valves that you have configured inside the <Host> element
  (such as the SingleSignOnValve if you turn it on, and the
  AccessLogValve).  The last one will be o.a.c.core.StandardHostValve
  which figures out which Context should handle the request by
  matching against context paths.  Again, it passes on to the
  invoke() method.

* o.a.c.core.StandardContext acts in a very similar manner, passing
  the request and response through the Valve pipeline you have
  configured.  Finally, o.a.c.core.StandardContextValve looks at your
  <servlet-mapping> definitions and figures out which servlet should
  process the request.  For each <servlet> definition, there is an
  instance of o.a.c.core.StandardWrapper.

* Yet again (Engine/Host/Context/Wrapper all implement the standard
  functionality of o.a.c.Container), the request and response are
  passed through the Valve pipeline (if any).  The final Valve will be
  o.a.c.core.StandardWrapperValve, which does the following:
  - Assembles a FilterChain if any filters have been defined
  - Calls the first filter in the chain
  - When the last filter calls FilterChain.doFilter(), the
    service() method of your servlet is *finally* called.

* Now, the stack unwinds as each invoke() call along the way returns.
  (But you can see from the above why you get such long exception
  stack traces when your servlet throws an exception :-).

If you are familiar with the "Gang of Four" design patterns book, this is
basically an implementation of the Chain Of Responsibility pattern.  It is
also very similar to the design pattern for Filters in Servlet 2.3, so you
can do the same sort of thing at the application level, but be portable to
any Servlet 2.3 container.

Craig


--
To unsubscribe:   <mailto:tomcat-user-unsubscribe@jakarta.apache.org>
For additional commands: <mailto:tomcat-user-help@jakarta.apache.org>
Troubles with the list: <mailto:tomcat-user-owner@jakarta.apache.org>


Mime
View raw message