Servlet体系结构 [JavaWeb][Servlet]

Servlet体系结构

图解:

Servlet体系结构 [JavaWeb][Servlet]_第1张图片

Generic 中文含义: 类的,通用的

我们将来开发B/S架构的Web项目都是针对于HTTP协议, 所以我们自定义Servlet类的时候直接继承HttpServlet抽象类就可以了

  • 注意: 我们的HttpServlet类也是一个抽象类

  • 我们继承了HttpServlet抽象类之后不用去实现Servlet接口中的五个抽象方法, 我们此时是继承抽象类的方式, 所以我们重写什么方法都取决于我们自己, 但是我们也不能随便重写, 我们重写方法之后肯定是要能满足我们的需求

    • 我们继承了HttpServlet抽象类之后不用去实现HttpServlet抽象类从Servlet接口中继承下来的service()方法, 我们在继承了HttpServlet抽象类之后要实现doXxx()方法, 我们一般目前都是实现doGet()方法和doPost()方法

    • eg:

      @WebServlet("/demo4")
      public class ServletDemo4 extends HttpServlet{
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
             System.out.println("Get...");
          }
          
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
             System.out.println("Post...");
          }
      }
      
      • 我们可以发现HttpServlet抽象类中明显就是根据请求方式的不同要调用不同的方法,那么为什么HttpServlet中要根据请求方式的不同调用不同的方法?
        • 因为我们的不同的请求方式下我们要根据不同的请求方式进行不同的逻辑处理
          • 以我们的Post请求和Get请求为例, Post请求的请求参数在请求体中, 而Get请求则没有请求体, Get请求的请求参数在请求行中的URL的后面, 我们要通过解析客户端发送过来的请求参数, 那么我们首先就要知道请求参数是在哪个位置, 然后我们才能去解析, 所以我们对于请求参数不同就只能是采用不同的解析方式

HttpServlet源码分析:

① 我们通过分析HttpServlet抽象类的源码可以发现, 我们其实HttpServlet抽象类中也是重写了Servlet接口中的service()方法, 在重写的Servlet接口的service()方法中将传入的ServletRequest和ServletResponse类型的对象向下转型为HttpServletRequest和HttpServletResponse类型的对象, 然后将向下转型后的HttpXxxXxx对象传入到HttpServlet抽象类自己编写的service()方法中

②等到HttpServlet抽象类自己的service()方法中我们又通过传入的HttpServletRequest对象调用getMethod()方法区获得对应的ServletRequest对象中封装的此时的请求数据的请求类型

③然后判断是那种请求类型, 我们就对应的去调用对应的doXxx()方法, 比如如果是Post请求的方式我们就是调用doPost()方法, 如果是get请求,那么我们就调用Get()方法, 所以我们继承HttpServlet抽象类创建的Servlet类只需要去重写对应的doXxx()方法即可

思路理清:

对应的当继承了HttpServlet抽象类而创建的Servlet类在被访问时, 我们的web容器(web服务器)还是会去调用对应的Servlet接口中的五种抽象方法中的service()方法, 这个时候调用其他四种方法的调用都是和实现Servlet接口时的调用是一样的, 但是对于service()方法有些不同, 这个时候web容器(web服务器)肯定还是会调用service方法进行逻辑处理, 但是此时我们继承了HttpServlet抽象类之后调用service()方法首先肯定是调用到HttpServlet抽象类中重写的Servlet类中的service()方法, 然后就执行我们上面的源码分析中的流程:

  • 先转型, 转型之后调用HttpServlet抽象类中的重载的service()方法
    • 这个重载的service()方法中的形参不是ServletRequest和ServletResponse类型的, 而是向下转型后的HttpServletRequest和HttpServletResponse类型的
  • 然后通过传入的HttpServletRequest类型的对象调用getMethod()方法获取对应的请求的请求方式, 是什么请求方式我们就会调用对应的doXxx()方法
这种方式我们就简化了如果是实现Servlet接口的时候代码书写繁琐的问题,因为如果我们是实现Servlet接口的时候就要先获取对应的请求方式, 然后根据请求方式的不同去调用不同的方法去获取和解析请求数据, 对于每次实现Servlet接口实现的Servlet类的开始都是先使用对应的ServletRequest向下转型为HttpServletRequest类型的对象, 然后就可以使用这个HttpServletRequest对象获取对应的请求的请求方式, 根据请求方式的不同调用不同的方法进行获取和解析请求数据
  • 后面我们会讲如何使用通用的方式获取get和post请求方式的请求参数数据
    • 但是其实通用的方式也是先获取对应的HttpServletRequest类型的对象, 使用对应的HttpServletRequest对象调用getMethod()方法获取对应的http请求的类型,根据请求的类型的不同调用不同的方法, 这样就实实现了通用方式获取get和post请求方式的请求参数数据

其中HTTP请求方式:

  1. DELETE(delete)
  2. HEAD(head)
  3. GET(get)
  4. OPTIONS(options)
  5. POST(post)
  6. PUT(put)
  7. TRACE(trace)
    • trace:中文含义: 追踪

补充:

Servlet接口是Javaweb中最顶级的接口

abstract class HttpServlet extends GenericServlet

abstract class GenericServlet implements Servlet

  • 注意: extends 和 implements后面都是加s的
    • 虽然java中类只能是多继承, 但是对于接口而言却是可以多继承和多实现的

补充二:

Servlet类中的无参构造方法, init()方法, service()方法, destroy()方法等等都是在幕后执行的, 而我们在台面上一般都是重写doPost()和doGet()方法

  • doPost()方法和doGet()方法都会在service()方法中被调用执行
  • 我们这里说的是继承HttpServlet抽象类的方式

你可能感兴趣的:(JavaWeb,java,spring,restful)