zoukankan      html  css  js  c++  java
  • JavaWeb 之 Servlet 体系结构

    一、Servlet 的体系结构

      1、Servlet 的体系结构示意图

      

      2、Servlet 类的继承体系

    二、体系结构剖析

      1、Servlet 接口

        Servlet 这个接口,里面只是定义了规范(面向接口编程),如果直接实现这个接口,需要重写里面所有的方法,但是经常使用 service() 方法,其他的不常用。其中定义了五个抽象方法,如下:

        

      2、GenericServlet 抽象类

        GenericServlet 抽象类将其继承的接口中的方法做了默认空实现,将service()方法继续作为抽象方法,供其子类去做实现:

        GenericServlet 继承结构:

        

        方法列表:

        

         可以看到 GenericServlet 类对 Servlet接口和ServletConfig接口中的方法做了实现,保留 service() 抽象方法供其子类实现。

      ServletConfig 接口

        在GenericServlet 类中还有一个属性 ServletConfig,这是一个关于当前 servlet 的配置类。

        关于源码:

    1     private transient ServletConfig config;
    2 
    3     public void init(ServletConfig config) throws ServletException {
    4       this.config = config;
    5       this.init();
    6     }
    7     public ServletConfig getServletConfig() {
    8       return config;
    9     }

        在 init(ServletConfig) 中通过参数的 config 来给属性赋值,并且还提供了一个 getServletConfig() 方法来获取此配置对象。

        同时还有一个 getServletContext() 方法,也可以帮助我们更方便的获取 ServletContext 对象。

          

      3、HttpServlet 抽象类

        HttpServlet 继承了 GenericServlet 类,对 HTTP 协议的一种封装,简化操作,其中主要是对 service() 方法的重写操作。

        HttpServlet 类结构:

          

        HttpServlet 类方法列表:

          

          本类中定义了多个常量和多个 do 系列的方法,为什么要这么做呢?

          源码分析:

     1     @Override
     2     public void service(ServletRequest req, ServletResponse res)
     3         throws ServletException, IOException
     4     {
     5         HttpServletRequest  request;
     6         HttpServletResponse response;
     7         
     8         if (!(req instanceof HttpServletRequest &&
     9                 res instanceof HttpServletResponse)) {
    10             throw new ServletException("non-HTTP request or response");
    11         }
    12 
    13         request = (HttpServletRequest) req;
    14         response = (HttpServletResponse) res;
    15 
    16         service(request, response);
    17     }
    18     
    19     //重载的 service 方法
    20     protected void service(HttpServletRequest req, HttpServletResponse resp)
    21         throws ServletException, IOException
    22     {
    23         String method = req.getMethod();
    24 
    25         if (method.equals(METHOD_GET)) {
    26             long lastModified = getLastModified(req);
    27             if (lastModified == -1) {
    28                 // servlet doesn't support if-modified-since, no reason
    29                 // to go through further expensive logic
    30                 doGet(req, resp);
    31             } else {
    32                 long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
    33                 if (ifModifiedSince < lastModified) {
    34                     // If the servlet mod time is later, call doGet()
    35                     // Round down to the nearest second for a proper compare
    36                     // A ifModifiedSince of -1 will always be less
    37                     maybeSetLastModified(resp, lastModified);
    38                     doGet(req, resp);
    39                 } else {
    40                     resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
    41                 }
    42             }
    43 
    44         } else if (method.equals(METHOD_HEAD)) {
    45             long lastModified = getLastModified(req);
    46             maybeSetLastModified(resp, lastModified);
    47             doHead(req, resp);
    48 
    49         } else if (method.equals(METHOD_POST)) {
    50             doPost(req, resp);
    51             
    52         } else if (method.equals(METHOD_PUT)) {
    53             doPut(req, resp);
    54             
    55         } else if (method.equals(METHOD_DELETE)) {
    56             doDelete(req, resp);
    57             
    58         } else if (method.equals(METHOD_OPTIONS)) {
    59             doOptions(req,resp);
    60             
    61         } else if (method.equals(METHOD_TRACE)) {
    62             doTrace(req,resp);
    63             
    64         } else {
    65             //
    66             // Note that this means NO servlet supports whatever
    67             // method was requested, anywhere on this server.
    68             //
    69 
    70             String errMsg = lStrings.getString("http.method_not_implemented");
    71             Object[] errArgs = new Object[1];
    72             errArgs[0] = method;
    73             errMsg = MessageFormat.format(errMsg, errArgs);
    74             
    75             resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
    76         }
    77     }

          前面当用不同的请求方式访问服务器时,我们需要根据请求的方式,进行不同的分发。而这个类帮助我们强转了 ServletRequest 对象,实现了分发处理。

          所以,HttpServlet 主要做了两件事:

          (1)重写了父类的 service() 方法;

          (2)重载了 service() 方法,完成分发处理;

          在我们自定义 Servlet 程序时只需要继承HttpServlet 类,然后根据业务重写 doGet() 与 doPost() 方法即可。

      4、自定义 Servlet 类

        当我们自定义的 Servlet 程序继承了 HttpServlet 类时,就可以根据业务选择不同的请求方法重写对应的方法,然后由 HttpServlet 来做分发:

        

  • 相关阅读:
    OpenSSH服务——密钥登录
    进程管理
    磁盘管理
    文件系统
    shell命令手册
    第一次常用命令手册
    远程连接mobaxterm安装使用
    Linux 系统CentOS 7 64 位安装
    PythonI/O进阶学习笔记_11.python的多进程
    PythonI/O进阶学习笔记_10.python的多线程
  • 原文地址:https://www.cnblogs.com/niujifei/p/15107721.html
Copyright © 2011-2022 走看看