🎉🎉🎉点进来你就是我的人了
博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!欢迎志同道合的朋友一起加油喔🤺🤺🤺
目录
1. 什么是Servlet?
2. 第一个Servlet程序
1. 创建maven项目(基于IDEA2021)
2. 引入依赖
3. 创建目录结构
4. 编写servlet代码
5. 打包
6. 部署
7. 验证程序
3.利用smart Tomcat 插件一键完成打包部署
3.1 安装smart Tomcat
3.2 如何进行一键操作
3.3 smart Tomcat的适用场景
4. 七大步骤总结
1. 什么是Servlet?
在了解Servlet前,先了解一下为什么需要Servlet
Servlet产生的背景
前面学习了Tomcat,它是一个Web服务器,提供Web程序处理服务端对请求的解析和对响应的封装,也就是请求的解析和响应的封装都不需要我们自己手动写程序来完成
比如我们将一个webapp(Web应用)部署到Tomcat中,如果自己写程序来处理请求和返回响应的内容,就需要调用Tomcat提供的API(Tomcat提供的类和接口中的方法和属性),如果此时更改Web服务器,我们自己写的请求解析和响应内容就无法使用了
Servlet是什么?
Servlet是一种实现动态页面的技术,所谓动态页面就是用户不同,时间不同,输入的参数不同,页面内容也不会发生变化,而静态页面是内容始终固定不变的,html就是静态的资源文件
Servlet为不同的JavaWeb服务器规定了响应的编程规范,它屏蔽Web服务器实现的细节(不同的服务器对请求的解析和响应的封装可以是不同的),但是定义好了统一的编程规范(统一的类,接口,方法),也就是换一个Web服务器,还可以使用
Servlet主要做的工作
- 允许程序员注册一个类,在服务器收到某个特定的HTTP请求的时候,执行这个类中的一些代码
- 帮助程序员解析HTTP请求,把HTTP请求从一个字符串解析为一个HttpRequest对象
- 帮助程序员构造HTTP响应,程序员只要给指定的HttpResponse对象填写一些属性字段,Servlet就会自动按照HTTP协议构造HTTP响应字符串,并通过Socket写回给客户端
2. 第一个Servlet程序
Maven项目的引入
- Maven是一个"构建工具",针对代码进行依赖管理、编译、打包、验证、部署等功能。我们之前写的代码,在IDEA中直接点击"运行"就可以运行了,这是因为之前写的代码都比较简单,也不需要将代码打包部署给别人来用
- 但如果是一个复杂的项目,依赖了很多的第三方库,同时自身还有很多的模块,模块之间也存在依赖关系,此时编译运行就没那么简单了,Maven可以视为是针对复杂项目进行管理的一个解决方案
- maven自身支持的功能有很多,我们下面主要使用两个功能:管理依赖和打包
- 管理依赖:如果在项目中想使用某个第三方库,就可以使用maven把这个库下载下来并导入到项目中
- 打包:把我们的代码编译好,将.class文件打包成压缩包(类似于.jar和.war这些)
我们直接基于IDEA内部现成的Maven来操作哈,首次创建项目会下载很多东西,
如果觉得下载过慢,可以参考我上一篇博客将maven源改为国内阿里云镜像
1. 创建maven项目(基于IDEA2021)
①选择Maven创建项目:
Maven Archetype是用来创建特定类型项目的模板,它的种类非常多,因为它可以由任何人创建并发布。以下是一些常见的官方和非官方的Maven Archetypes:
maven-archetype-quickstart: 这是最基本的Archetype,它创建一个包含简单Java类和单元测试的项目。
maven-archetype-webapp: 这个Archetype创建一个简单的Java web应用,包括一个servlet和一个JSP,以及相关的Web配置。
maven-archetype-j2ee-simple: 这个Archetype创建一个简单的J2EE应用,包含一个EJB模块和一个Web模块。
maven-archetype-simple: 这个Archetype创建一个非常简单的Maven项目,不包含任何特定的代码或者目录结构。
maven-archetype-mojo: 这个Archetype创建一个Maven插件项目。
spring-boot-archetype: 这是Spring Boot项目的官方Archetype,创建一个Spring Boot应用。
jersey-quickstart-webapp: 这是Jersey框架的官方Archetype,创建一个RESTful Web服务。
appengine-standard-archetype: 这是Google App Engine的官方Archetype,创建一个可以部署到Google App Engine的应用。
以上只是众多Archetype中的一部分。实际上,任何人都可以创建并发布他们自己的Maven Archetype,这意味着存在着大量的Archetypes,可以用来创建各种类型的项目。你可以在Maven的官方网站,或者其他第三方网站,查找更多的Archetypes。
很多大佬实现了很多的第三方库,这些第三方库就是统一把他们放到中央仓库里面的,方便用户去查找。
②创建好项目后的目录结构:
③如何使用Maven项目:
最常用的就是如上图的打包操作,但是不仅仅是如此,图中罗列的所有都可以实现的。
④pom.xml的简介
在Maven中,pom.xml是一个非常重要的配置文件,它描述了项目的基本信息和项目的构建配置。POM全称为Project Object Model,即项目对象模型。
groupId:定义当前Maven项目所属的实际项目组。通常采用反向的公司网址作为组织的标识,例如 com.mycompany。这类似于Java的包名用于避免类名冲突的方式。
artifactId:定义实际项目的名称。例如,你可能正在为你的项目 "my-app" 创建一个Maven项目。在这种情况下,artifactId将是 "my-app"。
version:定义实际项目的版本。这通常与实际项目的发布周期相对应。例如,你可能在开发 "my-app" 的1.0版本,那么version就应该是 "1.0"。
这三个元素组合在一起形成一个坐标,唯一标识了一个项目在所有的Maven项目中的位置。
2. 引入依赖
Maven项目创建完,会生成一个pom.xml文件,我们需要在pom.xml中引入Servlet API依赖的jar包
注意:Servlet的版本要和Tomcat匹配,如果我们使用Tomcat 8.5,就需要使用Servlet 3.1.0
附上查询版本对应关系链接:Tomcat与Servlet版本对应链接
(1) 去中央仓库上找到servlet 的驱动包。(中央仓库地址)
(2) 选择3.1版本
(3) 导入依赖
将上述红框内容复制粘贴到pom.xml中
图中的红色部分表示暂时还未下载安装,刷新一下IDEA就会自动调用maven,从中央仓库下载该jar包,首次下载可能时间较长,大家需要耐心等待。
3. 创建目录结构
虽然Maven帮我们创建了一些目录,但是还是不够,不足以支撑我们写一个servlet项目,所以还需要我们手动再创建一些目录和文件出来。
①在src/main的路径下创建一个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>
此处web.xml文件中报错不要紧张,idea对非java代码的识别并不准确,不影响代码运行
4. 编写servlet代码
编写代码是在java中创建类实现的。
①各方面注意事项:
在网络程序中,就涉及到一对相当重要的概念:
请求:request
响应:responsedoGet方法要做的工作,就是根据请求,计算生成响应。
②一个服务器的工作流程,可以分为三个典型的步骤:
(1)接收请求并解析
(2)根据请求计算响应
(3)构造响应数据,并返回给客户端
这里面,(1)(3)这两步,Tomcat已经帮我们做好了。因此我们只需要实现(2),也就是doGet要实现的内容。举个通俗的例子:
我去一个饭店点餐,我点了一份蛋炒饭,那在商家接到我的单之后,就会给后厨,其中一个人会去装一碗饭,同时,另一个打鸡蛋,另一个人开始准备炒,这三个行为可以看做三个线程的并发操作,最后炒好了,商家又端给我。这三个人的工作就相当于在请求计算响应的过程。
③对下面的解释
@WebServlet("/hello")
在类上方加上@WebServlet("/hello")注解,表示Tomcat收到的请求中,路径为/hello的请求才会调用HelloServlet这个类的代码
④综合代码如下:
- 创建一个类HelloServlet,继承HttpServlet
- 在类上方加上@WebServlet("/hello")注解,表示Tomcat收到的请求中,路径为/hello的请求才会调用HelloServlet这个类的代码
- 重写doGet方法,doGet方法的参数有两个,分别表示收到的HTTP请求和要构造的HTTP响应,这个方法会在Tomcat收到GET请求时触发
- HttpServletRequest表示HTTP请求,Tomcat按照HTTP请求的格式,把字符串格式的请求转化成了一个HttpServletRequest对象,后续想获得请求中的信息(方法,url,header,body等)都是通过这个对象来获取的
- HttpServletResponse表示HTTP响应,在代码中把响应构造好(构造响应的状态码,header,body等)
- resp.getWriter()是获取响应对象的输出流,通过输出流可以写入一些数据,写入的数据被构造一个HTTP响应的body部分,Tomcat会把整个响应转化为字符串,通过Socket写回给浏览器
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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//这是在服务器的控制台中,打印了字符串(服务器能看到,但是客户端看不到)System.out.println("hello world");//这是给resp(HTTP响应)的body中写入字符串hello world,这个内容就会被HTTP响应发回给浏览器,显示到浏览器页面上//这里为了表示Tomcat的页面所呈现的是动态的,不是静态的html,所以用了System.currentTimeMillis()来展示resp.getWriter().write("hello world "+System.currentTimeMillis());} }
5. 打包
我们仔细观察,可以发现上面我们写的代码,是没有main方法的,也就是不能够运行,因此我们需要把当前的代码打包,然后部署到Tomcat中,再通过Tomcat来进行调用。
①找到打包所在位置:
②进行相关准备操作:修改pom.xml
jar和war都是java发布程序的压缩包格式。war算是给Tomcat专门搞的,这里不光会包含一些.class,还可以包含配置文件,以及依赖的第三方jar,还有html,css,js......
③判断打包完成:
并且我们可以在目录这边看到
6. 部署
把war包拷贝到Tomcat的webapps目录下
然后打开Tomcat 服务器
服务器启动后挂在后台不要关闭,否则开启失败
7. 验证程序
直接输入对应的网址向服务器发送请求,检查服务器能否响应并返回浏览器页面
注意!!!每当我们刷新页面时,就会得到不同的数值,这是因为通过java代码生成的内容是可变的,而HTML中的内容是静态的,是不可变的。
3.利用smart Tomcat 插件一键完成打包部署
对于上述的七大步骤,我们会发现,每次修改代码的时候,都需要重新打包,部署。这个样子是相当麻烦的,所以我们尝试通过IDEA上的插件,直接把Tomcat给集成进来了,从而做到“一键式”完成打包部署。但是我们需要哦注意的是!!!Tomcat和IDEA是两个独立的程序,Tomcat并不是IDEA的一部分,不要搞混。
3.1 安装smart Tomcat
①安装:
②配置:(只有第一次需要进行配置,后续不需要)
配置完成点击ok即可
3.2 如何进行一键操作
配置完成点击下方按钮即可一键自动打包部署
看到以下内容说明打包部署成功
在浏览器输入对应的网址向服务器发送请求,检查服务器能否响应并返回浏览器页面
3.3 smart Tomcat的适用场景
- smart tomcat的运行方式和之前拷贝到webapps中,是存在本质区别的.
- smart tomcat其实是使用了Tomcat另外一种运行方式.在运行Tomcat的时候,通过特定的参数,来指定Tomcat加载某个特定目录中的webapp
因此,上述过程,既不会打包,也不会拷贝~~(你打开 tomcat的 webapps看到里面没啥变化)
这种方式只适用开发和调试阶段~~如果是部署到生产环境,还是得打war包,然后拷贝
4. 七大步骤总结
后续针对代码进行了任何修改, 都需要重新进行 5 - 7 的步骤.
1-3 步,创建一个项目, 只要操作一次就好了 , 而 4 - 5 步, 每修改一次代码,都需要重复操作一次, 此处的 4 和 7 是省不了的, 可以针对 5,6 进行简化操作, 就是用 IDEA 的插件 smart tomcat.
5. Servlet 运行原理
在 Servlet 的代码中,我们并没有写 main 方法,那么对应的 doGet 方法的代码是如何被调用的呢?响应又是怎么返回给浏览器的?
必须明确:我们自己实现 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 中的数据按照一定的格式显示在浏览器的界面上。