• 【Java Web】Servlet规范讲解


    目录

    一、前言

    二、Servlet规范介绍

    2.1 常见版本及新功能

    2.2 Servlet的作用

    2.3 Servlet的本质

    三、Servlet接口和实现类

    3.1 Servlet接口

    3.2 Servlet接口实现类示例

    3.3 Servlet接口实现类开发步骤

    3.3.1 关键点

    3.3.2 引入Servlet源码包

    1、描述

    Servlet接口是一类完成Java与服务器之间的桥梁,若想让Java和服务器产生联系,Java必须实现由服务器提供的Servlet接口。类似于数据库驱动和JDBC,JDBC是Java的接口,数据库想和Java产生联系就必须实现Java的JDBC接口。

    2、Tomcat自带引入

    3.3.3 Servlet接口实现类的编写

    1、第一步

    2、第二步

    3、第三步

    3.4 Tomcat调用Servlet接口实现类

    1、创建Servlet实现类对象

    2、调用service()方法

    3、调用doGet() 或 doPost()

    四、Servlet与Http服务器

    4.1 Servlet与Http服务器通信原理

    4.2 浏览器与servlet通信原理

    4.3 总结


    一、前言

    Java Web应用中,除了Tomcat服务器外,其实还有Jetty、GlassFish、Undertow等多种Web服务器。

    一个Java Web App通常打包为.war文件,并且可以部署到Tomcat、Jetty等多种Web服务器上。为什么一个Java Web App基本上可以无修改地部署到多种Web服务器上呢?原因就在于Servlet规范。

    Servlet规范是Java Servlet API的规范,用于定义Web服务器如何处理HTTP请求和响应。Servlet规范有一组接口,对于Web App来说,操作的是接口,而真正对应的实现类,则由各个Web Server实现,这样一来,Java Web App实际上编译的时候仅用到了Servlet规范定义的接口,只要每个Web服务器在实现Servlet接口时严格按照规范实现,就可以保证一个Web App可以正常运行在多种Web服务器上:

    二、Servlet规范介绍

    Servlet也算是JavaEE规范中的一种。

    对于Web应用程序,Servlet规范是非常重要的。Servlet规范有好几个版本,每个版本都有一些新的功能。

    2.1 常见版本及新功能

    Servlet 1.0:定义了Servlet组件,一个Servlet组件运行在Servlet容器(Container)中,通过与容器交互,就可以响应一个HTTP请求;

    Servlet 2.0:定义了JSP组件,一个JSP页面可以被动态编译为Servlet组件;

    Servlet 2.4:定义了Filter(过滤器)组件,可以实现过滤功能;

    Servlet 2.5:支持注解,提供了ServletContextListener接口,增加了一些安全性相关的特性;

    Servlet 3.0:支持异步处理的Servlet,支持注解配置Servlet和过滤器,增加了SessionCookieConfig接口;

    Servlet 3.1:提供了WebSocket的支持,增加了对HTTP请求和响应的流式操作的支持,增加了对HTTP协议的新特性的支持;

    Servlet 4.0:支持HTTP/2的新特性,提供了HTTP/2的Server Push等特性;

    Servlet 5.0:主要是把javax.servlet包名改成了jakarta.servlet

    Servlet 6.0:继续增加一些新功能,并废除一部分功能。

    目前最新的Servlet版本是6.0,我们开发Jerrymouse Server也是基于最新的Servlet 6.0。

    2.2 Servlet的作用

    • 在servlet规范中,指定【动态资源文件】开发步骤(限定开发人员的编写)。只有继承了servlet接口的实现类编写出来的 .class文件,才是动态资源文件,才允许给服务器调用(服务器只能调用Servlet接口实现类的 动态资源文件)。
    • 在servlet规范中,指定Http服务器调用动态资源文件的规则(限定服务器的访问),服务器创建出动态资源文件的实例对象,然后实例对象调用动态资源文件内的方法,得到某些执行结果将结果返回给服务器;
    • 在servlet规范中,指定Http服务器管理动态资源文件实例对象规则(限定服务器的访问)。服务器可以对所有的动态资源文件进行管理;

    2.3 Servlet的本质

    servlet是一堆具有"固定编写格式"的Java接口,提供一种"限定"来编写服务器可以访问的动态资源文件。

    狭义的 Servlet 是指 Java 语言实现的一个接口,广义的 Servlet 是指任何实现了这个 Servlet 接口的类。Servlet对象会被方法Servlet容器中,一个容器可以放多个Servlet对象

    三、Servlet接口和实现类

    3.1 Servlet接口

    Servlet接口来自于Servlet规范下的一个接口,这个接口存在于Http服务器提供jar包中。如 Tomcat服务器的lib目录下 的servlet-api.jar存放着Servlet接口(javax.servlet.Servlet接口)。

    Servlet规范中认定,Http服务器能调用的动态资源文件 必须是一个Servlet接口实现类的 .class文件。

    接口代码:

    1. // Tomcat服务器下的Servlet接口源码
    2. // 所有Tomcat调用的动态资源文件必须实现该接口
    3. package javax.servlet;
    4. import java.io.IOException;
    5. public interface Servlet {
    6. // 负责初始化Servlet对象。在Servlet对象创建后,Servlet容器将调用init()方法,完成Servlet对象的初始化工作。
    7. void init(ServletConfig var1) throws ServletException;
    8. // 负责响应客户端的请求。当Servlet容器接收到客户端要求访问特定Servlet对象的请求时,就会调用该Servlet对象的service()方法,完成响应工作。
    9. // 接口提供的五个方法中,只有Service()方法需要实现类重写实现
    10. void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
    11. // 负责释放Servlet对象占用的资源。当Servlet容器决定将Servlet对象从内存中销毁时,就会调用该Servlet对象的destroy()方法,完成销毁工作。
    12. void destroy();
    13. // Servlet接口还定义了以下两个返回Servlet的相关信息的方法。
    14. // JavaWeb 应用中的程序代码可以访问Servlet的这两个方法,从而获得Servlet的配置信息及其他相关信息。
    15. // 返回一个ServletConfig对象,该对象包含Servlet的初始化参数和Servlet容器的引用。
    16. ServletConfig getServletConfig();
    17. // 返回一个字符串,该字符串包含Servlet的版本信息、版权信息、作者信息等。
    18. String getServletInfo();
    19. }

    3.2 Servlet接口实现类示例

    1. class Student{
    2. // 非Servlet接口,不是动态资源文件,Tomcat无权调用
    3. }
    4. class Teacher implements Servlet{
    5. // 实现Servlet接口,合法的动态资源文件,Tomcat有权利调用
    6. // Tomcat创建Servlet对象,调用其方法
    7. Servlet obj = new Teacher();
    8. obj.doGet()
    9. }

    3.3 Servlet接口实现类开发步骤

    3.3.1 关键点

    • 浏览器提交的方式:get 或 post;
    • Http服务器接收请求后的处理方式:HttpServlet类的Service()方法体中采用请求体对象getMethod()获取;
    • 动态资源文件的本质:是Servlet接口实现类
    • 动态资源文件的编写规则:先getMethod()获取浏览器提交请求的方式,解析请求的URL,查找资源,执行结果,返回资源。

    3.3.2 引入Servlet源码包

    1、描述
    Servlet接口是一类完成Java与服务器之间的桥梁,若想让Java和服务器产生联系,Java必须实现由服务器提供的Servlet接口。类似于数据库驱动和JDBC,JDBC是Java的接口,数据库想和Java产生联系就必须实现Java的JDBC接口。
    2Tomcat自带引入

    在IDEA引入Tomcat时 详情请见,Tomcat就自带引入servlet-api.jar包

    3.3.3 Servlet接口实现类的编写

    1、第一步

    创建一个Java类,并继承于HttpServlet父类(HttpServlet间接实现了Servlet接口),使该Java类成为一个服务器可调用的Servlet接口实现类;

    1. /**
    2. * extends extends implements
    3. * Servlet实现类-------->(abstract)HttpServlet-------->(abstract)GenericServlet----------> servlet接口
    4. */
    5. public class MyServletTest01 extends HttpServlet {
    6. }
    2、第二步

    重写HttpServlet父类的两个方法-- doGet() 或 doPost(),一般只重写一个具体的即可,在另外一个重写的方法内互相调用。但doGet() 或 doPost()的具体调用不需要程序员指定,而是由HttpServlet抽象类的Service()方法自动根据浏览器提交的方式判断 来调用,程序员只需要重写doGet() 和 doPost()满足需求即可

    • 浏览器get方式提交请求,服务器调用ServletInstance的doGet()方法;
    • 浏览器post方式提交请求,服务器调用ServletInstance的doPost()方法。
    1. // 实现HttpServlet,并重写doGet() 和 doPost()
    2. public class MyServletTest01 extends HttpServlet {
    3. @Override
    4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    5. super.doGet(req, resp);
    6. }
    7. @Override
    8. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    9. doGet(req, resp);
    10. }
    11. }
    3、第三步

    将Servlet接口实现类信息注册到Tomcat服务器,具体是在web.xml文件中添加已实现的Servlet接口实现类信息标签。

    网站目录(项目)---> web目录 ---> WEB-INF目录 ---> web.xml文件

    1. "1.0" encoding="UTF-8"?>
    2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
    5. version="4.0">
    6. <servlet>
    7. <servlet-name>MyServletservlet-name>
    8. <servlet-class>com.yry.controller.MyServletTest01servlet-class>
    9. servlet>
    10. <servlet-mapping>
    11. <servlet-name>MyServletservlet-name>
    12. <url-pattern>/MyServleturl-pattern>
    13. servlet-mapping>
    14. web-app>

    3.4 Tomcat调用Servlet接口实现类

    1、创建Servlet实现类对象

    Tomcat服务器有权创建Servlet实现类对象(动态资源文件实例对象),Tomcat通过创建Servlet实现类对象来执行对应的Servlet动态资源文件。

    1. // 创建Servlet实现类对象
    2. Servlet servletInstance = new servletInstance();

    2、调用service()方法

    Tomcat创建出Servlet实现类对象后,调用HttpServlet的service()方法来处理浏览器提交的请求。

    1. // 调用service()方法处理浏览器请求,service()方法中封装了处理浏览器请求的方式
    2. servletInstance.service();

    3、调用doGet() doPost()

    doGet() 或 doPost()的具体调用不需要程序员指定,而是由HttpServlet抽象类的Service()方法自动根据浏览器提交的方式判断来调用。

    1. /**不需要关心:
    2. * HttpServlet类中封装了service()可以决定具体调用doGet() 或 doPost()
    3. * service(){
    4. * if(请求方式 == GET){
    5. * this.doGet
    6. * }else if(请求方式 == POST){
    7. * this.doPost
    8. * }
    9. * }
    10. */
    11. // 只需要关心:实现HttpServlet,并重写doGet() 和 doPost()
    12. public class MyServletTest01 extends HttpServlet {
    13. @Override
    14. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    15. super.doGet(req, resp);
    16. }
    17. @Override
    18. protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    19. doGet(req, resp);
    20. }
    21. }

    四、ServletHttp服务器

    4.1 ServletHttp服务器通信原理

    Servlet与Http服务器交流图:

    4.2 浏览器与servlet通信原理

    • 第一步:浏览器输入URL,在URL的最后面是动态资源文件的简短servlet名;
    • 第二步:浏览器提交URL请求,可选择get 或 post提交方式;
    • 第三步:Http服务器将URL转变成二进制;
    • 第四步:Http服务器根据二进制形式URL中的简短servlet名 到web.xml中匹配查找对应的servlet(具体是匹配web.xml中的标签中的名字);
    • 第五步:Http服务器在web.xml内部根据标签中的servlet简短名 找到同文件中 的名字,最后找到真正的Servlet接口实现类;
    • 第六步:Http服务器找到Servlet接口实现类后,创建Servlet接口实现类对象;
    • 第七步:Http服务器创建Servlet接口实现类对象后,(继承的体现)调用父类HttpServlet的service()方法,获取浏览器提交请求的方式;
    • 第八步:Http服务器从HttpServlet处确定浏览器提交请求的方式,执行Servlet接口实现类中对应的doGet() 或 doPost()方法;
    • 第九步:将Servlet接口实现类执行doGet()或doPost()方法后的结果 返回给Http服务器;
    • 第十步:Http服务器将执行结果(包含返回的数据)转成二进制数据,原路发送回给浏览器。

    4.3 总结

    总的来说,当Servlet容器接收到用户的HTTP请求后,由容器负责把请求转换为HttpServletRequestHttpServletResponse对象,分别代表HTTP请求和响应,然后,经过若干个Filter组件(过滤器)后,到达最终的Servlet组件,由Servlet组件完成HTTP处理,将响应写入HttpServletResponse对象:

    其中,ServletContext代表整个容器的信息,如果容器实现了ServletContext接口,也可以把ServletContext可以看作容器本身。ServletContextHttpServletRequestHttpServletResponse都是接口,具体实现由Web服务器完成。FilterServlet组件也是接口,但具体实现由Web App完成。此外,还有一种Listener接口(监听器),可以监听各种事件,但不直接参与处理HTTP请求,具体实现由Web App完成,何时调用则由容器决定。因此,针对Web App的三大组件:ServletFilterListener都是运行在容器中的组件,只有容器才能主动调用它们。(此处略去JSP组件,因为我们不打算支持JSP)

    对于Jerrymouse服务器来说,开发服务器就必须实现Servlet容器本身,容器实现ServletContext接口,容器内部管理若干个ServletFilterListener组件。

    对每个请求,需要创建HttpServletRequestHttpServletResponse实例,查找并匹配合适的一组Filter和一个Servlet,让它们处理HTTP请求。

    在处理过程中,会产生各种事件,容器负责将产生的事件发送到Listener组件处理。

    以上就是我们编写Servlet容器按照Servlet规范所必须的全部功能。


    原文链接:https://www.jianshu.com/p/20cba5429c85

  • 相关阅读:
    Linux Framebuffer 实验
    JWT的创建
    Java面试题:讨论单例模式的实现方式,包括懒汉式和饿汉式,并讨论线程安全问题
    架构师的职位需求
    浅浅的 常见的滤波算法
    Fabric.js 使用图片遮盖画布(前景图)
    【Linux】Linux常用操作命令(三)
    高级 ECharts 技巧:自定义图表主题与样式
    基于SpringBoot+Vue的足球社区管理系统(源码+lw+部署文档+讲解等)
    Gin框架Go Web项目实战
  • 原文地址:https://blog.csdn.net/cy973071263/article/details/132747274