zoukankan      html  css  js  c++  java
  • servlet与tomcat

    1、servlet与servlet容器

     (1)servlet本质

       前方高能,请注意、注意、注意。。。重要的事情说三遍,servlet本质就是一个Java接口 ,目的在于定义一套处理网络请求的规范,如下所示:

    package javax.servlet;
    
    import java.io.IOException;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public interface Servlet {
        void init(ServletConfig arg0) throws ServletException;
    
        ServletConfig getServletConfig();
    
        void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException;
    
        String getServletInfo();
    
        void destroy();
    }

      所有实现servlet接口的类,都要实现接口中的五个方法,其中最主要的是两个生命周期方法 init()和destroy()、处理请求的service(),即:

    • 初始化的作用;
    • 销毁后的作用;
    • 收到请求后需要做什么。

     init() 和 destroy()方法只执行一次, 即servlet的生命周期---创建和销毁,而service()方法每次有新请求到达时都会调用,即处理处理实际业务。

    (2)servlet容器

      全称server applet,意为服务程序。主要作用是给上级容器(Tomcat)提供doGet()和doPost()等方法。其生命周期实例化、初始化、调用、销毁受控于Tomcat容器。

     (3)request/response

      request:浏览器发起http请求,请求到达tomcat,经tomcat封装成了request对象(将请求头、请求地址、请求参数等进行了封装);

      response:浏览器发起http请求到达tomcat容器时,产生一个空的response对象,http请求数据经过servlet处理,将处理后结果封装成response对象,经过tomcat处理后,组装成HTTP响应返回给浏览器。

     (4)web容器

      可以部署多个WEB应用程序的环境。Tomcat容器属于web容器的一种,web容器还包括weblogic容器、JBoss容器等;而Tcomcat、webLogic等包含servlet容器。

      

      注:三层架构实质是对servlet的拆分,目的在于解耦合。

    2、tomcat

    (1)tomcat程序入口main()

      main方法是启动一个java程序的入口,任何程序都会有自己的main方法,tomcat是一个WEB容器,也不例外:

    //TODO 以下为伪代码,目的在于说明tomcat执行原理
    public static void main(String args[]) {
           //TODO 初始化运行环境,载入需要的jar包,读取conf/server.xml,生成相应的运行对象:
            if (daemon == null) {
                Bootstrap bootstrap = new Bootstrap();
                try {
                    bootstrap.init();//初始化守护进程
                } catch (Throwable t) {
                    return;
                }
                daemon = bootstrap;
            } 
       //TODO 装载,开始运行。
            try {
                String command = "start";
                if (command.equals("startd")) {
                    daemon.load(args);
                    daemon.start();//启动Tomcat
                } else if (command.equals("stopd")) {
                    args[args.length - 1] = "stop";
                    daemon.stop();//停止Tomcat守护进程
                } 
            } catch (Throwable t) {
            }
        }

    (2)tomcat创建的resques和response

     

    (3)tomcat对servlet接口的实现

       逻辑层级关系:

        abstract class GenericServlet implements Servlet, ServletConfig,Serializable

        abstract class HttpServlet extends GenericServlet

    public abstract class HttpServlet extends GenericServlet {
    
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            String protocol = req.getProtocol();
            String msg = lStrings.getString("http.method_get_not_supported");
            if (protocol.endsWith("1.1")) {
                resp.sendError(405, msg);
            } else {
                resp.sendError(400, msg);
            }
        }
        
        //TODO doHead doPut doDelete
    
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            String protocol = req.getProtocol();
            String msg = lStrings.getString("http.method_post_not_supported");
            if (protocol.endsWith("1.1")) {
                resp.sendError(405, msg);
            } else {
                resp.sendError(400, msg);
            }
        }
    
        protected void service(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            String method = req.getMethod();
            long errMsg;
            if (method.equals("GET")) {
                errMsg = this.getLastModified(req);
                if (errMsg == -1L) {
                    this.doGet(req, resp);
                } else {
                    long ifModifiedSince;
                    try {
                        ifModifiedSince = req.getDateHeader("If-Modified-Since");
                    } catch (IllegalArgumentException arg8) {
                        ifModifiedSince = -1L;
                    }
    
                    if (ifModifiedSince < errMsg / 1000L * 1000L) {
                        this.maybeSetLastModified(resp, errMsg);
                        this.doGet(req, resp);
                    } else {
                        resp.setStatus(304);
                    }
                }
            }  else if (method.equals("POST")) {
                this.doPost(req, resp);
            } else {
                String errMsg1 = lStrings.getString("http.method_not_implemented");
                Object[] errArgs = new Object[] { method };
                errMsg1 = MessageFormat.format(errMsg1, errArgs);
                resp.sendError(501, errMsg1);
            }
        }
    
        public void service(ServletRequest req, ServletResponse res)
                throws ServletException, IOException {
            HttpServletRequest request;
            HttpServletResponse response;
            try {
                request = (HttpServletRequest) req;
                response = (HttpServletResponse) res;
            } catch (ClassCastException arg5) {
                throw new ServletException(lStrings.getString("http.non_http"));
            }
    
            this.service(request, response);
        }
    }
    (4)web容器的部署

      部署的过程其实就是解析 xml 实例化对象,并触发和处理容器及组件对应生命周期事件的过程。在 Tomcat 中,一个 Context 实例就代表一个 Web 应用程序,所以部署的第一步就是创建一个 StandardContext 对象。在创建时 HostConfig 首先会查找 Context 描述符,它可能在两个位置:

    • $CATALINA_BASE/conf/<engine>/<host>/[webappname].xml
    • $CATALINA_BASE/webapps/webappname/META_INF/context.xml

      如果两个位置都不存在此文件,则使用 conf/context.xml 默认配置。

      Context 实例化后会触发 init 和 start 生命周期事件:

    • init - 会创建用于解析 context.xml 和 web.xml 的工具 Digester 的实例,并解析context.xml
    • start - 则会根据 web.xml 部署描述符实例化 Servlet、Filter、Listener 等 Web 组件

      感谢阅读,参考了不少大佬资料,如需转载,请注明出处 https://www.cnblogs.com/huyangshu-fs/p/13173474.html

  • 相关阅读:
    HTML-DOM实例——实现带样式的表单验证
    HTML-DOM常用对象的用法(select/option/form/table)
    C++程序嵌入Python解释器二次开发
    线程池、协程
    Qt信号(SINGAL)与槽(SLOT)
    随机数
    字符串、内存拷贝
    模板元编程以及关键字template和typename
    std::thread,std::future,std::promise,std::async
    C++智能指针,RAII(资源获取即初始化) 原则
  • 原文地址:https://www.cnblogs.com/huyangshu-fs/p/13173474.html
Copyright © 2011-2022 走看看