关闭

Tomcat源码阅读之处理请求

标签: tomcat源码处理请求页面跳转jspServlet
120人阅读 评论(0) 收藏 举报
分类:

web开发中我们常见的请求类型有三种: 1、页面跳转请求。 2、ajax请求。3、请求静态资源,如图片,css文件等。那么我们以最常用的页面跳转请求为例看看Tomcat的处理流程。Tomcat处理请求的逻辑主要在StandardWrapperValve类的invoke方法中。
接收到页面跳转请求之后,Tomcat首先会创建JspServlet实例,但是该实例在Context容器启动的时候就已经被创建,因此StandardWrapper的allocate方法直接返回JspServlet实例。接着获取请求的路径,本次请求的路径为/user/login.jsp,这个路径会赋值给request的org.apache.catalina.core.DISPATCHER_REQUEST_PATH属性。然后Tomcat会创建过滤器工厂对象和过滤器链。

// Create the filter chain for this request
        ApplicationFilterFactory factory =
            ApplicationFilterFactory.getInstance();
        ApplicationFilterChain filterChain =
            factory.createFilterChain(request, wrapper, servlet);
            。。。。。。略
            filterChain.doFilter
                            (request.getRequest(), response.getResponse());

有了这两个对象之后就可以通过过滤器链逐个执行过滤器里的逻辑了。注意此处的request.getRequest()和response.getResponse()方法,这两个方法获取到的不是request和response对象本身,而是经过再次封装的门面类RequestFacade和ResponseFacade。使用门面类能够防止其他类直接访问request和response对象中的数据或方法,只能访问通过门面类对外提供的接口,这样就保证了程序更加安全。接着该执行过滤器的逻辑了,我们知道过滤器的执行过程封装在ApplicationFilterChain类的internalDoFilter方法中,具体的执行过程可以翻看前面过滤器部分。执行完过滤器里的逻辑之后就该执行Servlet中的逻辑了。

servlet.service((HttpServletRequest) request,
                                    (HttpServletResponse) response);

这一步是执行Servlet逻辑的入口,然后调用HttpServlet类的public void service(ServletRequest req, ServletResponse res)方法,HttpServlet的service并没有进行任何处理,接着调用了JspServlet的service方法,然后创建jsp编译器jspCompiler对象,最终来到了HttpJspBase类的service方法。

public final void service(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException 
    {
        _jspService(request, response);
    }

这个方法里面并没有什么实质性的逻辑处理,并且这个方法是被final修饰的,因此不能被继承,那么子类也不能重写这个方法了,也就是说jsp的处理逻辑并不在HttpJspBase类中。这个时候我们打开Tomcat的work/Catalina/localhost目录,在跟我们web应用同名的文件夹下,会发现一个跟我们请求路径同名的文件/user/login.java,只不过由.jsp变成了.java文件。打开login.java文件,我们会发现在_jspService方法中有很多out.write语句,这些语句输出的内容刚好是一个完整的jsp文件,内容与login.jsp完全一致。虽然这个文件的名字叫login.java,但是文件中的类名却是login_jsp,而且继承了HttpJspBase类,而HttpJspBase类继承了HttpServlet,因此login_jsp是一个Servlet。于是Tomcat处理页面跳转请求的流程总结起来就是Tomcat将jsp文件编译成一个Servlet类,通过Servlet类中的out.write输出原jsp中的内容。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:8362次
    • 积分:384
    • 等级:
    • 排名:千里之外
    • 原创:31篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类