Java-Servlet解析

news2024/9/23 23:33:48

文章目录

  • 前言
  • Servlet
    • 定义
    • 内部解析
      • 总结servlet接口
      • 实际应用的servlet
        • GenericServlet类和HttpServlet类
    • HttpServlet中的设计模式
      • 首先看一下模板方法的定义
      • 逐步解析
    • SpringMVC应用

前言

从事Javaweb项目开发有一段时间了,一直不理解它是怎么一回事,后来查询资料发现这里面涉及到几个东西,分别是tomcat、JavaEE中13个规范之一的servlet、以及springMVC。于是就去学习了一下,发现这里里面都是围绕这servlet进行的操作。于是就有了今天的这个总结。

Servlet

定义

Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。
狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器
关于web服务器有很多种,其中常用的有tomcat、Netty,还有微软的IIS(Internet Information Services),
本文中用到的web服务器为tomcat

内部解析

既然说到这个servlet是一个规范,一般说到规范都是接口,就好比我们在项目开发过程中,前端开发工程师和后端的开发工程师都是根据接口文档去进行开发的,双方都遵守这个接口文档,那么开发过程就会减少很多不必要的麻烦。所以下图就是Servlet在Java中的结构展示。

image.png

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

下面是servlet接口内部方法的展示一共是有5个方法

  • 第一个init(javax.servlet.ServletConfig servletConfig)
    这个方法在servlet对象初始化的时候执行,只执行一次。
  • 第二个getServletConfig()
    这个方法获取的是在web.xml中配置的参数比如:
    image.png
  • 第三个service(javax.servlet.ServletRequest servletRequest, javax.servlet.ServletResponse servletResponse)
    这个service方法就不得了了,这个方法就是我们具体要用到的请求接口方法了,通俗点讲就是,在web项目中将我们的业务代码可以放到这个service方法,当我们在项目中配置好了servlet的映射以后去调用请求,tomcat调用的就是这个方法。后面会具体演示,在实际开发中现在已经不是直接去实现了servlet接口了,而是重写HttpServlet这个类中的doGet和doPost方法。
  • 第四个getServletInfo()
    当Servlet容器(如Tomcat)需要提供有关Servlet的信息时,它会调用getServletInfo()方法。通常情况下,这些信息用于管理和监视Servlet的部署和执行过程。例如,当管理员查看部署在Servlet容器中的应用程序时,可能会显示Servlet的名称、描述、版本号等信息。
  • 第五个destroy()
    当Servlet容器(如Tomcat)需要关闭或卸载Servlet时,它会调用Servlet的destroy()方法。这通常发生在以下情况下:
    服务器关闭:当服务器关闭或重新启动时,Servlet容器会通知所有正在运行的Servlet执行销毁操作,以确保它们可以正确地释放资源。
    Servlet被卸载:当应用程序的Servlet被从Servlet容器中卸载时,容器会先调用destroy()方法,然后才会将Servlet从容器中移除。
    在destroy()方法中,Servlet可以执行一些清理任务,如释放打开的文件、关闭数据库连接、取消注册的监听器等。这是一个用于资源清理和释放的重要时机,以确保应用程序的正常关闭和资源的正确释放。

总结servlet接口

以上这些内容是JavaEE的servlet接口中定义的方法,这些方法中initdestroy都是只会执行一次,也就是说当tomcat程序启动,servlet中的这两个方法只会被调用一次,分别是创建servlet对象和销毁servlet时,那么大家肯定会问,既然只调用一次,哪是谁调用的呢?答案就是web容器去调用的,在web项目中我们写的代码最后都是由tomcat去执行的,但是tomcat怎么知道要调用你哪些类的哪些方法呢?为了解决这个问题,就有了这个servlet这个规范了,tomcat只去关注去实现了servlet接口的这些类,其它的类它不会去调用。

实际应用的servlet

上面的小总结说了,servlet是由tomcat去调用的,也就是说只要我们自己写的代码去实现了servlet的接口,并且在web.xml中配置了,那么当tomcat启动时它就会把我们自己写的servlet去给创建对象。
但是我们在实际应用的时候自己写的servlet类并没有去直接实现的servlet而是去继承的抽象类HttpServlet,这里大家就有疑问了,问什么不直接去实现servlet接口,却要去继承一个抽象类呢?这里就需要给大家说一下咱们一开始放出来的servlet的一个结构图(类图关系)了,image.png

GenericServlet类和HttpServlet类

GenericServlet类和HttpServlet类是Java Servlet API中的两个重要类,用于实现Servlet的基本功能。

  1. GenericServlet类:

    • GenericServlet是一个抽象类,实现了Servlet接口。
    • 它提供了Servlet的基本实现,可以被继承并用于创建自定义的Servlet。
    • GenericServlet适用于所有类型的协议,不仅限于HTTP协议。
    • 它简化了Servlet的编写,通过提供默认的空实现,使得开发者只需重写感兴趣的方法即可。
    • GenericServlet中最重要的方法是service(),用于处理客户端请求。默认情况下,它会委托给doGet(), doPost()等方法,可以在子类中进行重写以实现特定的请求处理逻辑。
    • 除了service()方法,GenericServlet还提供了其他有用的方法,如getServletConfig()getServletInfo(),用于获取Servlet的配置信息和描述信息。
  2. HttpServlet类:

    • HttpServletGenericServlet的子类,专门用于处理基于HTTP协议的请求。
    • 它扩展了GenericServlet,提供了更方便处理HTTP请求的方法和功能。
    • HttpServlet通过重写doGet()doPost()doPut()等方法,可以根据请求类型执行相应的处理逻辑。
    • 它还提供了一系列的钩子方法(如doHead()doDelete()doOptions()等),用于处理特定的HTTP请求方法。
    • HttpServlet还提供了一些用于处理HTTP请求的辅助方法,如获取请求参数、处理会话和Cookie等。

总结来说,GenericServlet类是一个通用的Servlet基类,适用于各种协议。而HttpServlet类是在GenericServlet基础上专门为HTTP协议提供了更方便的处理方法和功能。一般情况下,开发基于HTTP协议的Servlet时,应该使用HttpServlet类作为基类,以便更好地处理HTTP请求和提供相应的功能。
web项目中基本上都是使用的http协议,所以我们自己写的servlet类都是继承HttpServlet类的,因为这个类帮我们做了相应的http协议解析。

HttpServlet中的设计模式

既然使用http协议进行通信,那么http协议的请求是不同类型,比如post、get、put等,那这些类型请求servlet是如何区分呢?因为在servlet接口中只有一个service方法会被tomcat调用呀!所以这里就用到了设计模式中行为型的模板方法了。

首先看一下模板方法的定义

  • 模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern), 指在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
  • 简单说, 模板方法模式定义一个操作中的算法的骨架,而将- -些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。

image.png

逐步解析

在HttpServlet中定义好了相应不同类型请求的方法

  • doGet,如果 servlet 支持 HTTP GET 请求
  • doPost,对于 HTTP POST 请求
  • doPut,对于 HTTP PUT 请求
  • doDelete,对于 HTTP 删除请求
    image.png
    只要继承了HttpServlet重写以上不同的方法就可以在有相应类型的请求时调用对应的方法。那大家肯定会想,这么多方法它是怎么知道我请求这个servlet时发出的是什么请求呢?这里就要说一下了,这个HttpServlet中已经解析了http请求,也就是说它解析了这个请求是什么类型,当它解析到这个请求是post类型时就会调用doPost方法,它是怎么调用的呢?这里就说到了模板方法的核心了,定义算法骨架。在HttpServlet中有一个方法叫做service方法,这个方法并不是实现的servlet接口的那个service方法,这两个有区别。
    image.png
  protected void service(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String method = req.getMethod();
        if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn't support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                if (ifModifiedSince < lastModified) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }
        } else if (method.equals(METHOD_HEAD)) {
            long lastModified = getLastModified(req);
            maybeSetLastModified(resp, lastModified);
            doHead(req, resp);
        } else if (method.equals(METHOD_POST)) {
            doPost(req, resp);        
        } else if (method.equals(METHOD_PUT)) {
            doPut(req, resp);         
        } else if (method.equals(METHOD_DELETE)) {
            doDelete(req, resp);         
        } else if (method.equals(METHOD_OPTIONS)) {
            doOptions(req,resp);            
        } else if (method.equals(METHOD_TRACE)) {
            doTrace(req,resp);           
        } else {
            //
            // Note that this means NO servlet supports whatever
            // method was requested, anywhere on this server.
            //

            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[1];
            errArgs[0] = method;
            errMsg = MessageFormat.format(errMsg, errArgs);
            
            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
        }
    }

image.png
所以当我们自己写的类继承了HttpServlet后去重新其中的doPost或者doGet等方法后会在HttpServlet中自定义的service方法中进行分发
image.png
可以看一下这个service方法中,有一个service方法调用,这是在调用HttpServlet中自定义的service方法进行后续的请求分发。
image.png

SpringMVC应用

说到这里就浅浅的说一下,SpringMVC的实现就是基于Servlet实现的,在配置mvc项目时用springMVC是需要在web.xml中进行配置的,大家可以看一下这个配置是什么。
image.png
再继续往下看,我们看一下SpringMVC中的核心类DispatcherServlet,可以看到,这个类其实也是实现了Servlet接口的。也就是说SpringMVC的实现是在基于Servlet开发的。
image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/611323.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Fiddler抓包工具之高级工具栏中的Inspectors的使用

高级工具栏中的Inspectors的使用 Inspectors 页签允许你用多种不同格式查看每个请求和响应的内容。JPG 格式使用 ImageView 就可以看到图片&#xff0c;HTML/JS/CSS 使用 TextView 可以看到响应的内容。Raw标签可以查看原始的符合http标准的请求和响应头。Cookies标签可以看到…

【Web服务应用】搭建LNMP架构

搭建LNMP架构 一、编译安装MySQL服务二、安装Nginx服务三、安装配置PHP解析环境四、部署Discuz社区论坛Web应用五、部署博客论坛应用六fpm进程优化 一、编译安装MySQL服务 1.安装MySQL环境依赖包 yum -y install gcc gcc-c ncurses ncurses-devel bison cmake2、创建运行用户 u…

NIMA: Neural Image Assessment

摘要:基于自动学习的图像质量评估技术在评价图像采集管道、存储技术和共享媒体等方面具有广泛的应用价值&#xff0c;近年来已成为图像质量评估研究的热点。尽管这一问题具有主观性&#xff0c;但现有的大多数方法仅对AVA[1]和TID2013[2]等数据集提供的平均意见得分进行预测。我…

电脑怎么录屏?推荐2个好用的win7录屏方法!

案例&#xff1a;win7电脑怎么录屏&#xff1f; 【我的电脑是win7系统&#xff0c;我想录制它的电脑屏幕。有没有小伙伴知道win7电脑怎么录屏&#xff1f;有没有适合win7电脑的录屏工具】 随着数字时代的发展&#xff0c;屏幕录制已经成为一种常见的需求。在教育、演示、游戏…

❤️爆肝熬夜开发了一个基于SSM的办公用品领用系统,现在开源给你!毕设面试学习都不愁了!❤️

大家好&#xff0c;我是兔哥&#xff0c;我又来分享项目啦。 1.写在前面 之前有个粉丝找到我&#xff0c;问有没有什么真正手把手的教SSM框架的视频&#xff0c;说网上找到的大都很复杂或者资料不全。 我说不需要整这么麻烦&#xff0c;我自己给你录一套手把手的教程吧。 ❤…

11.发请求

微信小程序可以请求 HTTPS 类型的接口&#xff08;HTTP不行&#xff09;&#xff0c;请求之前必须将 接口的域名 添加到 信任列表 中 小程序中没有跨域问题&#xff0c;且使用JS原生XML对象发Ajax请求是无效的 目录 1 查看信任的域名 2 添加信任的域名 3 发起GET请求 …

为什么“零信任“对于数据备份和灾难恢复至关重要

零信任模型作为一种突破性的数据备份和安全方法已经崭露头角。近年来&#xff0c;随着网络攻击的蔓延&#xff0c;传统的安全措施已不再足够。据预测&#xff0c;仅在2023年&#xff0c;全球企业因网络犯罪将损失超过8万亿美元。这一惊人的数字凸显了企业迫切需要采取更全面的数…

【方法】如何以“副本方式”打开PPT文件?

在工作中&#xff0c;我们经常需要对PPT文件进行多次修改后才能确定最终版本。 在修改时&#xff0c;如果不想修改原始的PPT文件&#xff0c;我们可以通过“以副本方式”打开PPT&#xff0c;这样PPT就会在原文档所在的文件夹里自动新建一份完全相同的PPT。 创建后对副本的编辑…

Prototypical networks for few-shot learning.

这篇论文是介绍《Prototypical Networks for Few-shot Learning》。作者公布了他的Pytorh代码。如果看不太懂原作者的代码话可以看一下这一个&#xff1a;https://github.com/orobix/Prototypical-Networks-for-Few-shot-Learning-PyTorch 0. Few-shot learning Few-shot lear…

一文通吃:从 ZooKeeper 一致性,Leader选举讲到 ZAB 协议与 PAXOS 算法(下)

本文首发自\[慕课网] &#xff0c;想了解更多IT干货内容&#xff0c;程序员圈内热闻&#xff0c;欢迎关注"慕课网"及“慕课网公众号”&#xff01; 作者&#xff1a;大能 | 慕课网讲师 上篇文章&#xff0c;我们介绍了ZooKeeper集群保证数据一致性和Zookeeper集群Le…

带你全面了解 OAuth2.0

最开始接触 OAuth2.0 的时候&#xff0c;经常将它和 SSO单点登录搞混。后来因为工作需要&#xff0c;在项目中实现了一套SSO&#xff0c;通过对SSO的逐渐了解&#xff0c;也把它和OAuth2.0区分开了。所以当时自己也整理了一篇文章《SSO单点登录原理及实现方式》 最近需要经常和…

STM32单片机GPS北斗无线防丢定位超出距离报警系统NRF24L01

实践制作DIY- GC0136-GPS北斗无线防丢定位超出距离报警系统 基于STM32单片机设计-GPS北斗无线防丢定位超出距离报警系统 二、功能介绍&#xff1a; 主机&#xff1a;STM32F103CxT6系列最小系统板OLED显示器NRF24L01无线通讯模块GPS北斗双模定位模块蜂鸣器距离加减2个按键1个模…

爬虫的操作

目录 爬虫基本 re/etree/beautifulsoup保存本地/连接数据库 基本 re lxml/etree beautifulsoup 保存到本地 传入数据库 大致分为 爬虫基本 re/etree/beautifulsoup保存本地/连接数据库 基本 爬一个很简单的百度新闻热搜 爬排名 热搜名 和热搜指数 百度热搜 我们直…

Lucid VS 特斯拉电驱系统

Lucid如何用更小的电机赶超特斯拉 Lucid 称其电机设计是小型化的&#xff0c;并且一直自夸其Air电动汽车中轻型且“紧凑“的电机轻便到可以放进登机行李箱中。然而&#xff0c;小型只是一个方面。Lucid的电机每个重只有67磅&#xff0c;能够产生670马力的动力&#xff0c;你没…

JAVA 生成微信小程序码-分享码

JAVA生成小程序码(太阳码) 工具类是获取token使用; appId 小程序appID appSecret 小程序秘钥 小程序中得配置分享项&#xff0c;不然图片是裂开的。 开发>开发管理>开发设置 nginx 配置 location ~ ^/share { #、share 你的访问路径default_type text/html;alias /d…

Dart 3.0 语法新特性 | 模式匹配 Patterns

theme: cyanosis 一、 Patterns 是什么 下面是官方对 Patterns 特性的说明 patterns :\ 从下面的第一句中可以知道&#xff0c;Patterns 是一种语法级的特性&#xff0c;而语法特性是一种语言的根基。 Patterns are a syntactic category in the Dart language, like statement…

10 缓存双写一致性之更新策略探讨

什么是缓存双写一致性 如果redis中有数据&#xff1a;需要和数据库中的值相同如果redis中无数据&#xff1a;数据库中的值要是最新值 缓存按照操作来分&#xff0c;有细分2种 只读缓存读写缓存 同步直写策略&#xff1a;写缓存时也同步写数据库&#xff0c;缓存和数据库中的…

如何移动下载文件夹到另一个盘?

下载文件夹占用了越来越多的C盘可用空间&#xff1f;本教程将教你如何安全易行地将下载文件夹移动到其他驱动器&#xff0c;以便你可以释放更多的C盘空间。 关于下载文件夹 从网站下载程序后它们会被存储在哪里&#xff1f;一般来说&#xff0c;当你从互联…

基于C++实现的智慧农业移动巡检系统设计(附源码)

Overview 项目源码 https://download.csdn.net/download/DeepLearning_/87863659 此项目开始于2023年2月7日&#xff0c;项目内容为一种AGV图形化操作系统&#xff0c;采用ROS2GO开发&#xff0c;开发环境为Ubuntu18.04、ROS melodic、Qt5.9.9&#xff0c;该项目作为23年挑战杯…

js函数this指向

目录 this的绑定规则  绑定一&#xff1a;默认绑定&#xff1b; ​ 绑定二&#xff1a;隐式绑定&#xff1b; ​ 绑定三&#xff1a;显式绑定&#xff1b; 通过call或者apply绑定this对象  绑定四&#xff1a;new绑定&#xff1b; 内置函数的绑定 this绑定规则的…