关于tomcat对请求处理流程的个人理解

为什么会写这个文章呢?
是在做项目的时候遇到了一个问题,问题如下:
用加密后url(*.htm)去访问tomcat的时候,需要对此url进行解码,所以就通过自定义的HttpServletRequestWrapper类在Filter中包装了request,此时url则变为(*.jsp),结果是tomcat还是以静态页面的处理方式对该请求进行处理,导致页面中的‘<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>’等jsp标签没有被解析。

于是就查看了一些tomcat源码,tomcat对请求的处理流程如下:
1)通过TcpWorkerThread获取socket,
2)调用Http11ConnectionHandler的process()对socket进行处理,
3)调用Http11AprProcessor的process()对socket进行处理,
4)调用CoyoteAdapter的service()对request进行处理,
5)调用StandardEngineValve、StanStandardEngineValvedardHostValve、StandardWrapperValve的invoke()方法对request进行处理,

这里重点要说的是StandardWrapperValve的invoke()方法:
1)

// Allocate a servlet instance to process this request
try {

if (!unavailable) {
                servlet = wrapper.allocate();// 由于这里url是*.htm,所以tomcat会分配一个htm的Servlet对此请求进行处理
        }
} catch (UnavailableException e) {
}
...
2)
// Create the filter chain for this request
ApplicationFilterFactory factory =
ApplicationFilterFactory.getInstance();
 ApplicationFilterChain filterChain =
        factory.createFilterChain(request, wrapper, servlet);// 为该请求创建相应的FilterChain
...
3)
// Call the filter chain for this request
// NOTE: This also calls the servlet's service() method
try {
...

// 调用filter、Servlet,由于这里的Servlet是在filter调用之前已经分配好的,所以在filter中修改url为*.jsp,并没有调用处理jsp的那个Servlet。
filterChain.doFilter(request.getRequest(),
                                    response.getResponse());
...
} catch (ClientAbortException e) {
}

以上只是个人的一些看法,还有一些疑问是IE是正常的,Firefox、Google是不行的,不知道是怎么回事?

又仔细看了一下tomcat源码,tomcat都调用DefaultServlet对该请求(*.htm),只不过IE不显示‘<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> ’而已。
如果是以‘*.htm’的方式访问Tomcat,Tomcat在请求到达时已为该请求分配好了相应的DefaultServlet去处理,所以在filter中修改是没有用的,代码如下:
public class CoyoteAdapter implements Adapter {
...
public void service(org.apache.coyote.Request req, 
                    org.apache.coyote.Response res)
        throws Exception {
...
// 分配相应的容器去处理该请求,
// 比如*.jsp(StandardEngine[Catalina].StandardHost[localhost].StandardContext[/rss].StandardWrapper[default])
if (postParseRequest(req, request, res, response)) {

猜你喜欢

转载自allen520.iteye.com/blog/1068495