详解Servlet的使用

news2024/11/26 5:50:48

目录

Servlet

定义

动态页面 vs 静态页面

主要功能

Servlet的使用

创建Maven项目

引入依赖

创建目录

编写代码

打war包

部署程序

验证程序

Smart Tomcat

安装Smart Tomcat

配置Smart Tomcat插件

启动Tomcat

访问页面

路径对应关系

Servlet运行原理

Tomcat的初始化

Tomcat处理请求

Tomcat的Service方法实现


Servlet

定义

Servlet(Server Applet)是Java Servlet的简称,是一种运行在Web服务器上的Java程序,用于处理客户端(通常是Web浏览器)的请求并生成响应。Servlet具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。

动态页面 vs 静态页面

静态页面也就是内容始终固定的页面. 即使 用户不同/时间不同/输入的参数不同 , 页面内容也不会发生变化. (除非网站的开发人员修改源代码, 否则页面内容始终不变). 
对应的, 动态页面指的就是 用户不同/时间不同/输入的参数不同, 页面内容会发生变化.

构建动态页面的技术有很多, 每种语言都有一些相关的库/框架来做这件事. 
Servlet 就是 Tomcat 这个 HTTP 服务器提供给 Java 的一组 API, 来完成构建动态页面这个任务.

主要功能

处理HTTP请求:Servlet可以接收来自客户端的HTTP请求,并根据请求执行相应的操作。
生成HTTP响应:Servlet处理完请求后,会生成相应的HTTP响应,并将其发送给客户端。
动态内容生成:Servlet能够生成动态的Web内容,如根据用户输入查询数据库并返回结果。

Servlet的使用
创建Maven项目

引入依赖

Maven 项目创建完毕后, 会自动生成一个 pom.xml 文件. 
我们需要在 pom.xml 中引入 Servlet API 依赖的 jar 包.

在Maven中央仓库搜索“Servlet”

然后点击“Java Servlet API”

选择和Tomcat版本匹配的Servlet版本

然后复制以下内容,粘贴到 pom.xml中

然后刷新Maven

创建目录

在src/main路径下创建一个和java目录同级的 webapp目录,然后再在 webapp目录下创建一个WEB-INF目录,然后再在WEB-INF目录下创建一个 web.xml文件,目录结构如下图所示:

然后在 web.xml文件中写入一下内容:

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>
</web-app>
编写代码

在 java 目录中创建一个类 HelloServlet, 代码如下:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("hello world");
        resp.getWriter().write("hello world");
    }
}

代码说明:

1.创建一个类 HelloServlet , 继承自 HttpServlet
2.在这个类上方加上 @WebServlet("/hello") 注解, 表示 Tomcat 收到的请求中, 路径为 /hello
的请求才会调用 HelloServlet 这个类的代码. (这个路径未包含 Context Path)
3.重写 doGet 方法. doGet 的参数有两个, 分别表示收到的 HTTP 请求 和要构造的 HTTP 响应. 这个方法会在 Tomcat 收到 GET 请求时触发

4.HttpServletRequest 表示 HTTP 请求. Tomcat 按照 HTTP 请求的格式把 字符串 格式的请求转成了一个 HttpServletRequest 对象. 后续想获取请求中的信息(方法, url, header, body 等) 都是通过这个对象来获取. 
5.HttpServletResponse 表示 HTTP 响应. 代码中把响应对象构造好(构造响应的状态码, header, body 等)
6.resp.getWriter() 会获取到一个流对象, 通过这个流对象就可以写入一些数据, 写入的数据会被构造成一个 HTTP 响应的 body 部分, Tomcat 会把整个响应转成字符串, 通过 socket 写回给浏览器.

打war包

IDEA中Maven打包默认是jar包,但是Tomcat要求是war包,因此我们需要修改pom.xml文件

然后双击package进行打包

然后我们就可以看到打的war包了

部署程序

把 war 包拷贝到 Tomcat 的 webapps 目录下.
启动 Tomcat , Tomcat 就会自动把 war 包解压缩.

验证程序

Smart Tomcat

手动拷贝 war 包到 Tomcat 的过程比较麻烦. 我们还有更方便的办法. 
下面我们使用 IDEA 中的 Smart Tomcat 插件完成这个工作.

安装Smart Tomcat

安装好以后,重启IDEA.

配置Smart Tomcat插件

然后点击"应用",“确定”即可。

启动Tomcat

访问页面

路径对应关系

使用 Smart Tomcat 部署的时候, 我们发现 Tomcat 的 webapps 内部并没有被拷贝一个 war 包, 
也没有看到解压缩的内容. 
Smart Tomcat 相当于是在 Tomcat 启动的时候直接引用了项目中的 webapp 和 target 目录.

Servlet运行原理
我们自己的实现是在 Tomcat 基础上运行的。
当浏览器给服务器发送请求的时候, Tomcat 作为 HTTP 服务器, 就可以接收到这个请求. 
HTTP 协议作为一个应用层协议, 需要底层协议栈来支持工作. 如下图所示:
更详细的交互过程可以参考下图:
1) 接收请求:
用户在浏览器输入一个 URL, 此时浏览器就会构造一个 HTTP 请求. 
这个 HTTP 请求会经过网络协议栈逐层进行 封装 成二进制的 bit 流, 最终通过物理层的硬件设备转换成光信号/电信号传输出去. 
这些承载信息的光信号/电信号通过互联网上的一系列网络设备, 最终到达目标主机(这个过程也需要网络层和数据链路层参与).
服务器主机收到这些光信号/电信号, 又会通过网络协议栈逐层进行 分用, 层层解析, 最终还原成HTTP 请求. 并交给 Tomcat 进程进行处理(根据端口号确定进程)
Tomcat 通过 Socket 读取到这个请求(一个字符串), 并按照 HTTP 请求的格式来解析这个请求, 根据请求中的 Context Path 确定一个 webapp, 再通过 Servlet Path 确定一个具体的 类. 再根据当前请求的方法 (GET/POST/...), 决定调用这个类的 doGet 或者 doPost 等方法. 此时我们的代码中的doGet / doPost 方法的第一个参数 HttpServletRequest 就包含了这个 HTTP 请求的详细信息.
2) 根据请求计算响应:
在我们的 doGet / doPost 方法中, 就执行到了我们自己的代码. 我们自己的代码会根据请求中的一些信息, 来给 HttpServletResponse 对象设置一些属性. 例如状态码, header, body 等.
3) 返回响应:
我们的 doGet / doPost 执行完毕后, Tomcat 就会自动把 HttpServletResponse 这个我们刚设置好的对象转换成一个符合 HTTP 协议的字符串, 通过 Socket 把这个响应发送出去. 
此时响应数据在服务器的主机上通过网络协议栈层层 封装, 最终又得到一个二进制的 bit 流, 通过物理层硬件设备转换成光信号/电信号传输出去. 
这些承载信息的光信号/电信号通过互联网上的一系列网络设备, 最终到达浏览器所在的主机(这个过程也需要网络层和数据链路层参与).
浏览器主机收到这些光信号/电信号, 又会通过网络协议栈逐层进行 分用, 层层解析, 最终还原成HTTP 响应, 并交给浏览器处理. 
浏览器也通过 Socket 读到这个响应(一个字符串), 按照 HTTP 响应的格式来解析这个响应. 并且把body 中的数据按照一定的格式显示在浏览器的界面上.
Tomcat的初始化

Tomcat 的代码中内置了 main 方法. 当我们启动 Tomcat 的时候, 就是从 Tomcat 的 main 方法开始执行的. 
被 @WebServlet 注解修饰的类会在 Tomcat 启动的时候就被获取到, 并集中管理. 
Tomcat 通过 反射 这样的语法机制来创建被 @WebServlet 注解修饰的类的实例.

这些实例被创建完了之后, 会点调用其中的 init 方法进行初始化. (这个方法是 HttpServlet 自带的, 我们自己写的类可以重写 init)
这些实例被销毁之前, 会调用其中的 destory 方法进行收尾工作. (这个方法是 HttpServlet 自带的, 我们自己写的类可以重写 destory)
Tomcat 内部也是通过 Socket API 进行网络通信. 
Tomcat 为了能同时相应多个 HTTP 请求, 采取了多线程的方式实现. 因此 Servlet 是运行在 多线程环境 下的.

Tomcat处理请求
Tomcat 从 Socket 中读到的 HTTP 请求是一个字符串, 然后会按照 HTTP 协议的格式解析成一个HttpServletRequest 对象. 
Tomcat 会根据 URL 中的 path 判定这个请求是请求一个静态资源还是动态资源. 如果是静态资源, 直接找到对应的文件把文件的内容通过 Socket 返回. 如果是动态资源, 才会执行到 Servlet 的相关逻辑. 
Tomcat 会根据 URL 中的 Context Path 和 Servlet Path 确定要调用哪个 Servlet 实例的 service 方法. 
通过 service 方法, 就会进一步调用到我们之前写的 doGet 或者 doPost
Tomcat的Service方法实现
Servlet 的 service 方法内部会根据当前请求的方法, 决定调用其中的某个 doXXX 方法. 
在调用 doXXX 方法的时候, 就会触发 多态 机制, 从而执行到我们自己写的子类中的 doXXX 方法.
欢迎大家访问我的主页!!!

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

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

相关文章

【Nginx从入门到精通】05-安装部署-虚拟机不能上网简单排错

文章目录 总结1、排查步骤 一、排查&#xff1a;Vmware网关二、排查&#xff1a;ipStage 1 &#xff1a;ping 127.0.0.1Stage 2 &#xff1a;ping 宿主机ipStage 3 &#xff1a;ping 网关 失败原因解决方案Stage 4 &#xff1a;ping qq.com 总结 1、排查步骤 Vmware中网关是否…

优化求解 | 非线性最小二乘优化器Ceres安装教程与应用案例

目录 0 专栏介绍1 Ceres库介绍2 Ceres库安装3 Ceres库概念3.1 构建最小二乘问题3.1.1 残差块3.1.2 代价函数 3.2 求解最小二乘问题 4 Ceres库案例4.1 Powell函数优化4.2 非线性曲线拟合 0 专栏介绍 &#x1f525;课设、毕设、创新竞赛必备&#xff01;&#x1f525;本专栏涉及…

Flink Transformation-转换算子

map算子的使用 假如有如下数据&#xff1a; 86.149.9.216 10001 17/05/2015:10:05:30 GET /presentations/logstash-monitorama-2013/images/github-contributions.png 83.149.9.216 10002 17/05/2015:10:06:53 GET /presentations/logstash-monitorama-2013/css/print/paper…

记录一些PostgreSQL操作

本文分享一些pg操作 查看版本 select version(); PostgreSQL 11.11 查看安装的插件 select * from pg_available_extensions; 查看分词效果 select ‘我爱北京天安门,天安门上太阳升’::tsvector; ‘天安门上太阳升’:2 ‘我爱北京天安门’:1select to_tsvector(‘我爱北京天…

【ubuntu】数学人的环境搭建

Python 语言环境 python 的 pip 第三方库管理 sudo apt install python3-pippython 的 idle 界面 sudo apt install idle3R 语言环境 sudo apt install r-cran-zoo### RStudio 界面 ubuntu sudo snap install rstudio --classicJulia 语言环境 sudo snap install julia --…

android 11添加切换分屏功能

引言 自Android 7开始官方就支持分屏显示,但没有切换分屏的功能,即交换上下屏幕。直到Android 13开始才支持切换分屏,操作方式是:分屏模式下双击中间分割线就会交换上下屏位置。本文的目的就是在Android 11上实现切换分屏的功能。 下图是Android13切换分屏演示 切换分屏…

数据结构——排序算法第一幕(插入排序:直接插入排序、希尔排序 选择排序:直接选择排序,堆排序)超详细!!!!

文章目录 前言一、排序1.1 概念1.2 常见的排序算法 二、插入排序2.1 直接插入排序2.2 希尔排序希尔排序的时间复杂度 三、选择排序3.1 直接选择排序3.2 堆排序 总结 前言 时间很快&#xff0c;转眼间已经到数据结构的排序算法部分啦 今天我们来学习排序算法当中的 插入排序 和 …

C++网络编程之多播

概述 在移动互联网时代&#xff0c;随着多媒体应用的日益普及&#xff0c;如何高效地将数据传输给多个接收者成为了网络通信领域的一个重要课题。多播&#xff08;英文为Multicast&#xff09;作为一种高效的网络通信方式&#xff0c;可以将数据同时发送到多个接收者&#xff0…

AWS的流日志

文章目录 一、aws如何观察vpc的日志&#xff1f;二、aws观测其vpc的入口日志三、 具体配置3.1、配置你的存储神器 S33.2、建立子网的流日志 一、aws如何观察vpc的日志&#xff1f; 排查问题的时候除了去抓包看具体的端口信息的时候&#xff0c;还可以根据其所在的vpc的子网信息…

C++ —— 以真我之名 如飞花般绚丽 - 智能指针

目录 1. RAII和智能指针的设计思路 2. C标准库智能指针的使用 2.1 auto_ptr 2.2 unique_ptr 2.3 简单模拟实现auto_ptr和unique_ptr的核心功能 2.4 shared_ptr 2.4.1 make_shared 2.5 weak_ptr 2.6 shared_ptr的缺陷&#xff1a;循环引用问题 3. shared_ptr 和 unique_…

DAMODEL丹摩|《ChatGLM-6B 在丹摩智算平台的部署与使用指南》

目录 一、引言 二、ChatGLM-6B 模型简介 ChatGLM-6B 的特点 三、DAMODEL 平台部署 ChatGLM-6B 1. 实例创建 2. 模型准备 3. 模型启动 四、通过 Web API 实现本地使用 1. 启动服务 2. 开放端口 3. 使用 PostMan 测试功能 4. 本地代码使用功能 五、总结 一、引言 Ch…

【AI大模型】LLM的检索增强--SELF-RAG

本篇博客参考论文&#xff1a; 《SELF-RAG: LEARNING TO RETRIEVE, GENERATE, AND CRITIQUE THROUGH SELF-REFLECTION》 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;大型语言模型&#xff08;LLMs&#xff09;已成为处理复杂语言任务的强大工具。然而&#xf…

Linux—进程概念学习-03

目录 Linux—进程学习—31.进程优先级1.1Linux中的进程优先级1.2修改进程优先级—top 2.进程的其他概念3.进程切换4.环境变量4.0环境变量的理解4.1环境变量的基本概念4.2添加环境变量—export4.3Linux中环境变量的由来4.4常见环境变量4.5和环境变量相关的命令4.6通过系统调用获…

C# 读取多条数据记录导出到 Word标签模板之图片输出改造

目录 应用需求 设计 范例运行环境 配置Office DCOM 实现代码 组件库引入 ​核心代码 调用示例 小结 应用需求 在我的文章《C# 读取多条数据记录导出到 Word 标签模板》里&#xff0c;讲述读取多条数据记录结合 WORD 标签模板输出文件的功能&#xff0c;原有输出图片的…

Android 性能优化:内存优化(理论篇)

内存作为App程序运行最重要的资源之一&#xff0c;需要运行过程中做到合理的资源分配与回收&#xff0c;不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏&#xff0c;重则导致用户应用程序发生 OOM&#xff08;out of memory&#xff09;崩溃。喜马直播随着近些年的业…

【AI技术赋能有限元分析应用实践】pycharm终端与界面设置导入Abaqus2024自带python开发环境

目录 一、具体说明1. **如何在 Windows 环境中执行 Abaqus Python 脚本**2. **如何在 PyCharm 中配置并激活 Abaqus Python 环境**3. **创建 Windows 批处理脚本自动执行 Abaqus Python 脚本**总结二、方法1:通过下面输出获取安装路径导入pycharm方法2:终端脚本执行批处理脚本…

arm学习总结

AHB总线连接的都是这些需要高速处理的内存、内核啥的 APB连接的都是些外设 GPIO并不需要高速处理的

【redis 】string类型详解

string类型详解 一、string类型的概念二、string类型的常用指令2.1 SET2.2 GET2.3 MSET2.4 MGET2.5 SETNX2.6 INCR2.7 INCRBY2.8 DECR2.9 DECRBY2.10 INCRBYFLOAT2.11 APPEND2.12 GETRANGE2.13 SETRANGE2.14 STRLEN 三、string类型的命令小结四、string类型的内部编码五、strin…

Mysql案例之COALESCE函数使用详解

hello&#xff0c;大家好&#xff0c;我是灰小猿&#xff01;最近在做一个三表关联查询的场景处理时&#xff0c;遇到了一个比较有用的MySQL函数&#xff0c;在这里记录一下&#xff0c;大概场景如下&#xff1a; 需求场景 场景&#xff1a;有一张object_rel表&#xff0c;表中…

C语言菜鸟入门·关键字·int的用法

目录 1. int关键字 1.1 取值范围 1.2 符号类型 1.3 运算 1.3.1 加法运算() 1.3.2 减法运算(-) 1.3.3 乘法运算(*) 1.3.4 除法运算(/) 1.3.5 取余运算(%) 1.3.6 自增()与自减(--) 1.3.7 位运算 2. 更多关键字 1. int关键字 int 是一个关键字&#xff0…