网络:Servlet的本质是什么?为什么要有Servlet?
发布日期:2022-03-16 03:25:40 浏览次数:38 分类:技术文章

本文共 3016 字,大约阅读时间需要 10 分钟。

Servlet的作用

servlet本质上是一个接口,它压根就不管也管不着哪些网络协议、http。

那servlet到底是干什么的呢?很简单,接口的作用是什么?规范呗!

在这里插入图片描述

servlet接口定义的是一套处理网络请求的规范,所有实现servlet的类,都需要实现它的那五个方法,其中最主要的是两个声明周期方法init()和destory(),还有一个处理请求的service()。也就是说,所有实现servlet接口的类,或者说,所有想要处理网络请求的类,都需要回答这三个问题:

  • 你初始化时要做什么?
  • 你销毁时要做什么?
  • 你接收到请求时要做什么?

这是Java给的一种规范!就像阿西莫夫的机器人三大定律、行尸走肉里Rick的那三个问题一样,规范!

servlet是一个规范,那实现了servlet的类,就能处理请求了吗?

  • 不能。你从来不会在servlet中写什么监听8080端口的代码,servlet不会直接和客户端打交道

  • 那请求是怎么来到servlet的呢?答案是servlet容器,比如我们最常用的Tomcat。servlet都是部署在一个容器中的,不然你的servlet根本不起作用

  • Tomcat才是与客户端直接打交道的家伙,它监听了端口,请求过来后,根据URL等信息,确定要将请求交给哪个servlet去处理,然后调用那个servlet的service方法,service方法返回一个response对象,Tomcat再把这个respond返回给客户端


Servlet本身在Tomcat中是“非常被动”的一个角色,处理的事情也很简单。网络请求与响应,不是它的主要职责,它其实更偏向于业务代码。所谓的request和respond是Tomcat传给它,用来处理请求和响应的工具,但它本身不处理这些。

Servlet的前世今生

所谓Tomcat其实是Web服务器和Servlet容器的结合体。

(1) Web服务器的所做的工作本质上是:

  • 将某个主机上的资源映射为一个URL供外界访问

(2) 那什么是servlet容器呢?

  • servlet容器,顾名思义里面存放的是servlet对象
  • 我们为什么能通过web服务器映射的URL访问到资源呢?肯定需要写程序处理请求,主要三个过程
    • 接收请求
    • 处理请求
    • 响应请求
  • 任何一个应用程序,必然包括这三个步骤。其中接收请求和响应请求是共性功能,而且没有差异性。于是,就可以把接收和响应两个步骤抽取成web服务器。

在这里插入图片描述

  • 处理请求的逻辑是不同的。没关系,抽取出来做成servlet,交给程序员自己编写

当然,随着互联网的发展,出现了三次架构,所以一些逻辑就从servlet抽取出来,分担到service和dao

在这里插入图片描述
但是servlet并不擅长往浏览器输出HTML页面,所以就出现了JSP。

等Spring家族出现后,Servlet开始退居幕后,取而代之的是SpringMVC。SpringMVC的核心组件DispacterServlet其实本质是一个Servlet,但是它已经自立门户,在原来HttpServlet的基础上,有封装了一层逻辑。

如何编写一个Servlet

查看接口方法:

在这里插入图片描述
五个方法,最难的地方在于形参,然而Tomcat会事先把形参对象封装好传给我们。除此之外,既不需要我们写TCP连接,也不需要我们解析HTTP请求,更不需要我们把结果转换成HTTP响应,request对象和response对象帮我们搞定了。

在Servlet里面主要写的代码都是业务逻辑,和原始的、底层的解析、连接等没有丝毫关系。最难的几个操作,人家已经给你封装成形参传进来了。

也就是说servlet虽然是个接口,但是实现类只是个空壳,我们写点业务逻辑就好了

在这里插入图片描述

总的来说,Tomcat已经帮我们完成了底层的操作,并且传入了三个对象:ServletConfig、ServletRequest、ServletResponse。

ServletConfig

ServletConfig即“servlet配置”,就是我们在web.xml中配置的servlet。它封装了servlet的一些参数信息。如果需要,我们可以从它获取。

在这里插入图片描述

Request/Response

这是接收请求和发送请求的类,Tomcat已经处理并封装好了,不需要servlet操心。HTTP请求到达Tomcat之后,Tomcat通过字符串解析,把各个请求头(Header)、请求地址(URL)、请求参数等都封装进Request对象中。通过调用

在这里插入图片描述

等方法,就可以得到浏览器当初发送的请求信息。

至于Response,Tomcat传给Servlet时,它还是空的对象。Servlet逻辑处理后得到结果,最终通过response.write()方法,将结果写入response内部的缓冲区。Tomcat会在servlet处理结束后,拿到response,遍历里面的信息,组装成HTTP响应发给客户端。

在这里插入图片描述

Servlet接口5个方法,其中init、service、destory是声明周期方法。init和destory各自只执行一次,即servlet创建和销毁时。而service会在每次有新请求到来时被调用。也就是说,我们主要的业务代码需要写在service中。

但是,浏览器发送请求基本的有两种:GET/POST。于是我们必须这样写

在这里插入图片描述

那能不能简化呢?

于是我们发现了一个GenericServlet,是个抽象类。

在这里插入图片描述
作用

  • 提升了init方法中原本是形参的servletConfig对象的作用域,方便其他方法使用
  • init方法中还调用了一个init空参方法,如果我们希望在servlet创建时做一些什么初始化操作,可以继承GenericServlet后,覆盖init空参方法
  • 由于需要其他方法也可以使用servletConfig,于是写了一个getServletConext。

但是service()方法没有实现。

于是又引入了一个HttpServlet

在这里插入图片描述
它继承了GenericServlet。

GenericServlet本身是一个抽象类,有一个抽象方法service。实现如下:

在这里插入图片描述
也就是说,HttpServlet的service方法已经替我们完成了复杂的请求方法判断。

问题是HttpServlet为什么要声明成抽象类呢?它的文档中注释了:

在这里插入图片描述
一个类声明成抽象方法,一般有两个原因:

  • 有抽象方法
  • 没有抽象方法,但是不希望被实例化

HTTPServlet做成抽象类,仅仅是为了不让new

在这里插入图片描述

它为什么不希望被实例化,而且要求子类重写doGet、doPost等方法呢?

我们来看一下源码:

在这里插入图片描述

如果我们没有重写会怎么样?

在这里插入图片描述
浏览器页面会显示405(http.method_get_not_supported)

也就是说,HttpServlet虽然在service中帮我们写了请求方式的判断。但是针对每一种请求,业务逻辑代码都是不同的,HttpServlet无法知晓子类想干嘛,所以就抽象出了7个方法,并且提供了默认实现:报405、400错误,提示请求不支持。

但是这种实现本身非常。。。简单来说等于没有。所以不能让它被实例化,不然调用doXXX方法是无用功。

在这里插入图片描述

这就是模板方法模式:父类把能写的逻辑都写完,把不确定的业务代码抽象成一个方法,调用它。当子类重写该方法,整个业务代码就活了

在这里插入图片描述

转载地址:https://blog.csdn.net/zhizhengguan/article/details/123125285 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:C/C++编程:log4cpp使用学习
下一篇:log4cpp源码阅读:Priority源码解析

发表评论

最新留言

不错!
[***.144.177.141]2024年04月18日 01时51分42秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

Linux 2021-06-29
jmeter-性能测试基础 2021-06-29
unittest 2021-06-29
错误推断法-维护中 2021-06-29
AJAX教程 2021-06-29
git基础 2021-06-29
git基础-01 2021-06-29
mysql-总结 2021-06-29
IPv4地址 2021-06-29
正则表达式 2021-06-29
redis 2021-06-29
术语-维护中 2021-06-29
software 2021-06-29
idea-ide 2021-06-29
technology 2021-06-29
spider-02 2021-06-29
spider-03 2021-06-29
spider-04 2021-06-29
spider-05 2021-06-29
spider-06 2021-06-29