你以为 Servlet 过时了?
1.1 Servlet 简介
1.1.1 概述
Servlet 的命名可以看出 sun 命名的特点,如 Applet 表示小应用程序;Scriptlet = Script + Applet,表示小脚本程序;同样 Servlet = Service + Applet,表示小服务程序。Servlet 是用 Java 编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态 Web 内容。 狭义的 Servlet 是指 Java 语言实现的一个接口,广义的 Servlet 是指任何实现了这个 Servlet 接口的类,一般情况下,人们将 Servlet 理解为后者。Servlet 运行于支持 Java 的应用服务器中。从原理上讲,Servlet 可以响应任何类型的请求,但绝大多数情况下 Servlet 只用来扩展基于 HTTP 协议的 Web 服务器。 最早支持 Servlet 标准的是 JavaSoft 的 Java Web Server,此后,一些其它的基于 Java 的 Web 服务器开始支持标准的 Servlet。
1.1.2 工作流程
Servlet 的主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。这个过程为: ♞ 客户端发送请求至服务器端; ♞ 服务器将请求信息发送至 Servlet; ♞ Servlet 生成响应内容并将其传给服务器。响应内容动态生成,通常取决于客户端的请求; ♞ 服务器将响应返回给客户端。
1.1.3 优点
方便 Servlet 提供了大量的实用工具例程,例如自动地解析和解码 HTML 表单数据、读取和设置 HTTP 头、处理 Cookie、跟踪会话状态等。 功能强大 在 Servlet 中,许多使用传统 CGI 程序很难完成的任务都可以轻松地完成。例如,Servlet 能够直接和 Web 服务器交互,而普通的 CGI 程序不能。Servlet 还能够在各个程序之间共享数据,使得数据库连接池之类的功能很容易实现。 可移植性好 Servlet 用 Java 编写,Servlet API 具有完善的标准。因此,为 IPlanet Enterprise Server 写的 Servlet 无需任何实质上的改动即可移植到 Apache、MicrosoftIIS 或者 WebStar。几乎所有的主流服务器都直接或通过插件支持 Servlet。 节省投资 不仅有许多廉价甚至免费的 Web 服务器可供个人或小规模网站使用,而且对于现有的服务器,如果它不支持 Servlet 的话,要加上这部分功能也往往是免费的。
1.1.4 Servlet 过时了吗?
Servlet 是规范之一,只是框架在底层帮我们实现了 Servlet,直观上感觉不到 Servlet 的存在,并不是说已经过时了,Servlet 在今后的长时间内还会被广泛使用。既然框架帮我们实现了 Servlet 我们是不是就可以不学了呢?确实,不学习 Servlet 也可以开发出项目,但是这不利于我们的技术提升,要想深刻的理解技术,必须深入了解它,剖析底层原理。
1.2 创建 Servlet
1.2.1 创建一个 Java EE 项目
打开 IDEA,选中创建 Java Enterprise 项目,勾选 Web Application。Application Server 一定要选,否则会找不到 jar 包
1.2.2 创建 MyServlet
创建 MyServlet 类实现 Servlet 接口及其抽象方法。
1.2.3 配置 web.xml
在 web/WEB-INF/
下,创建项目时勾选了 create web.xml 会自动创建。web 3.0 以后可以使用 @WebServlet("资源路径")
代替
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置 servlet -->
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>cn.gh.servlet.MyServlet</servlet-class>
</servlet>
<!-- servlet 映射路径 -->
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
</web-app>
1.2.4 启动项目
① 配置 Tomcat
② 添加项目
③ 启动 Tomcat
1.2.5 访问 servlet
Tomcat 访问路径(并不是 localhost:8080 而是 Tomcat 配置时的 URL)后跟上我们在 web.xml 配置的映射路径就可以访问到 Servlet
1.2.6 执行原理
① 当服务器接受到客户端浏览器的请求后,会解析请求 URL 路径,获取访问的 Servlet 的资源路径
② 查找 web.xml 文件,是否有对应的<url-pattern>
标签体内容。
③ 如果有,则在找到对应的<servlet-class>
全类名
④ tomcat 会将字节码文件加载进内存,并且创建其对象
⑥ 调用其方法
1.3 Servlet 生命周期
Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程: ♞ Servlet 通过调用 init () 方法进行初始化。 ♞ Servlet 调用 service() 方法来处理客户端的请求。 ♞ Servlet 通过调用 destroy() 方法终止(结束)。 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。需要注意的是,Servlet 对象一旦创建就会驻留在内存中等待客户端的访问,直到服务器关闭或 Web 应用被移除出容器时,Servlet 对象才会销毁。
1.3.1 初始化阶段
当客户端向 Servlet 容器发出 HTTP 请求要求访问 Servlet 时,Servlet 容器首先会解析请求,检查内存中是否已经有了该 Servlet 对象,如果有,则直接使用该 Servlet 对象,如果没有,则创建 Servlet 实例对象,然后通过调用 init() 方法实现 Servlet 的初始化工作。需要注意的是,在 Servlet 的整个生命周期内,它的 init() 方法只能被调用一次。
1.3.2 运行阶段
这是 Servlet 生命周期中最重要的阶段,在这个阶段中,Servlet 容器会为这个请求创建代表 HTTP 请求的 ServletRequest 对象和代表 HTTP 响应的 ServletResponse 对象,然后将它们作为参数传递给 Servlet 的 service() 方法。service() 方法从 ServletRequest 对象中获得客户请求信息并处理该请求,通过 ServletResponse 对象生成响应结果。 在 Servlet 的整个生命周期内,对于 Servlet 的每一次访问请求,Servlet 容器都会调用一次 Servlet 的 service() 方法,并且创建新的 ServletRequest 和 ServletResponse 对象,也就是说,service() 方法在 Servlet 的整个生命周期中会被调用多次。
1.3.3 销毁阶段
当服务器关闭或 Web 应用被移除出容器时,Servlet 随着 Web 应用的关闭而销毁。在销毁 Servlet 之前,Servlet 容器会调用 Servlet 的 destroy() 方法,以便让 Servlet 对象释放它所占用的资源。在 Servlet 的整个生命周期中,destroy() 方法也只能被调用一次。
1.3.4 示例
我们第一次访问 servlet 时,可以看到 init 执行了一次,service 执行了一次,再次访问时,只有 service 执行了,当我们关闭 tomcat 时 destroy 执行了一次。
- MYSQL5.7开启慢查询日志
- 微信又是一次大更新,下拉多任务切换 各种有趣小游戏
- 人工智能有可能超越人类大脑?
- 一种简单的数据库性能测试方法
- xiaomao.com7位数高价成交,并已启用建站
- Docker基于已有的镜像制新的镜像-Docker for Web Developers(3)
- 如何通过Remoting实现双向通信
- jenkins 入门教程(上)
- 让jQuery Tools Scrollable控件在Mobile Web里面支持resize功能
- CentOS6.5上golang环境配置
- 马斯克频发推文,或在揭示特斯拉明年大动作?
- yum安装出现No package nodejs available解决办法
- InfoPath中repeationg section动态填充数据
- CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 聊聊claudb的NotificationManager
- windows下安装Postman
- 【Pytorch 】笔记七:优化器源码解析和学习率调整策略
- 【Pytorch 】笔记六:初始化与 18 种损失函数的源码解析
- logstash index 生成时间晚 8 小时
- top 命令查看cpu利用率超过500%
- 【Pytorch 】笔记四:Module 与 Containers 的源码解析
- 控制pod内container执行顺序的几种姿势
- 本地部署istio多集群(共享控制面)
- elasticsearch unassigned shard
- 【Pytorch 】笔记五:nn 模块中的网络层介绍
- docker浅入深出4
- BFE.dev前端刷题#58. 获取DOM tree高度
- 如何在Tungsten Fabric上整合裸金属服务器(附配置验证过程)
- 逐行阅读Spring5.X源码(三) BeanDefinition的实现类详解,拔高