Servlet (上篇)

哥几个来学 Servlet 啦 ~~

目录

🌲一、什么是 Servlet

🌳二、第一个 Servlet 程序

🍇1. 创建项目

🍈2. 引入依赖

🍉3. 创建目录

🍊4. 编写代码

🍋5. 打包程序

🥭6. 部署程序

🍍7. 验证程序

🌴三、更方便的部署方式

🍁1. 安装 Smart Tomcat 插件

🍂2. 配置 Smart Tomcat 插件

🌵四、Servlet 的运行原理

🌾五、Servlet 的生命周期


 

🌲一、什么是 Servlet

        Servlet 是一种实现 动态页面 的技术,是一组 Tomcat 提供给程序员的 API,定义了 Java 类 被浏览器访问到(被 Tomcat 识别)的规则,能够帮助程序员简单高效地开发一个 web app

那么问题来了,什么是 动态页面?

我们先来认识一些什么是 静态页面:

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

比如 Tomcat 的主页:

动态页面:

        动态页面 指的就是 用户不同/时间不同/输入的参数不同,页面的内容发生变化。

比如我们的 CDSN :

🌳二、第一个 Servlet 程序

🍇1. 创建项目

注意:这里我们使用的不再是 “intelliJ” ,而是 “Maven” 。

🍈2. 引入依赖

Maven 项目创建完毕后,会自动生成一个 pom.xml 文件。

我们需要在 pom.xml 中引入 Servlet API 依赖的 jar 包:

🍕① 在中央仓库搜

Maven Repository: Search/Browse/Explore (mvnrepository.com)https://mvnrepository.com/🍔② 然后搜索 "servlet",一般第一个结果就是:

🍟③ 选择版本,Servlet 的版本要和 Tomcat 匹配,如果我们使用 Tomcat 8.5, 那么就需要使用 Servlet 3.1.0 版本。

🌭④ 把中央仓库中提供的 xml 复制到项目的 pom.xml 中

首先要在 这段代码的外围加上 dependencies 标签:

  

然后再将代码复制进去

porn.xml的完整代码是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ServletHelloWorld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

🍉3. 创建目录

当项目创建好了之后,IDEA 会帮我们自动创建出一些目录:

这些目录中:

  •  src 表示源代码所在的目录
  • main/java 表示源代码的根目录。后续创建.java 文件就放到这个目录中
  • main/resources 表示项目的一些资源文件所在的目录
  • test/java 表示测试代码的根目录

除了这些目录,我们还需要创建一些新的目录/文件

🍖① 创建 webapp 目录 在 main 目录下,和 java 目录并列,创建一个 webapp 目录

🍗② 创建 web.xml 然后在 webapp 目录内部创建一个 WEB-INF 目录,并创建一个 web.xml 文件

🥩③ 编写 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>

这些代码,我们可以看成是一些约定,可以帮助我们将资源部署到 Tomcat 里~~

        webapp 目录就是未来部署到 Tomcat 中的一个重要目录,我们可以往 webapp 中放一些静态资源,比如 html,css 等。

        在这个目录中还有一个重要的文件 web.xmlTomcat 找到这个文件才能正确处理 webapp 中的动态资源。

🍊4. 编写代码

在 java 目录中创建一个类 HelloServlet让它实现 Servlet 的接口重写 Servlet 的方法

代码如下:

import javax.servlet.*;
import java.io.IOException;

@WebServlet("/hello")
public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("Hello Servlet");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {

    }
}

这个的作用是提供路径 url,待会执行程序时会用到这个 url~~

 千万不要漏了  “ hello ”  前面的 “ / ” !!!!!

这上面的五个方法,我们待会儿再详细讲。

我们目前只在 service() 方法里加了一行代码而已:

🍋5. 打包程序

使用 maven 进行打包,打开 maven 窗口,然后展开 Lifecycle ,双击 package 即可进行打包:

 如果比较顺利的话,能够看到 SUCCESS 这样的字样:

        如果代码/配置/环境存在问题,可能会提示 BUILD FAILED,可以根据具体提示的错误信息具体解决。

打包成功后,可以看到在 target 目录下,生成了一个 jar 包:

这样的 jar 包并不是我们需要的,Tomcat 需要识别的是另外一种 war 包格式。

jar 包和 war 包的区别:

  • jar 包是普通的 java 程序打包的结果,里面会包含一些 .class 文件。

  • war 包是 java web 的程序,里面除了会包含 .class 文件之外,还会包含 HTML、CSS、 JavaScript、图 片、以及其他的 jar 包。打成 war 包格式才能被 Tomcat 识别!!!

另外这个 jar 包的名字太复杂了,我们也希望这个名字能更简单一点。

因此,我们需要:

🧇① 在 pom.xml 中新增一个 packing 标签,表示打包的方式是打一个 war 包:

<packaging>war</packaging>

🥞② 在 pom.xml 中再新增一个 build 标签,内置一个 finalName 标签,表示打出的 war 包的名字是 HelloServlet:

<build>
    <finalName>HelloServlet</finalName>
</build>

完整的 pom.xml 如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>ServletHelloWorld</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>


    <packaging>war</packaging>

    <build>
        <finalName>HelloServlet</finalName>
    </build>

</project>

重新使用 maven 打包,可以看到生成的新的 war 包的结果:

🥭6. 部署程序

把 war 包拷贝到 Tomcat 的 webapps 目录下:

启动 Tomcat , Tomcat 就会自动把 war 包解压缩:

🍍7. 验证程序

此时通过浏览器访问 127.0.0.1:8080/HelloServlet/hello

这个路径里的:

“127.0.0.1:8080” 是环回地址

“HelloServlet” 是我们的文件名

“hello” 则是这里面的url 

就可以看到结果了(结果在 Tomcat 服务器上显示的):

我们多次点击刷新,那么 Tomcat 服务器就会多次执行 service() 方法里的代码:

🌴三、更方便的部署方式

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

🍁1. 安装 Smart Tomcat 插件

🥗① 菜单 -> 文件 -> Settings

🥙② 选择 Plugins,选择 Marketplace,搜索 "tomcat",点击 "Install"

🥪③安装完毕之后,会提示 "重启 IDEA" 

🍂2. 配置 Smart Tomcat 插件

🍘① 点击右上角的 "Edit Configurations"

🍙② 选择左侧的 "Smart Tomcat"

🍚③ 在 Name 这一栏填写一个名字(可以随便写)

在 Tomcat Server 这一栏选择 Tomcat 所在的目录,其他的选项不必做出修改。

其中 Context Path 默认填写的值是项目名称 ,这会影响到后面咱们的访问页面

🍛④ 点击 OK 之后,右上角变成了

点击绿色的三角号,IDEA 就会自动进行编译、部署、启动 Tomcat 的过程

 此时 Tomcat 日志就会输出在 IDEA 的控制台中,可以看到现在就不再乱码了。

🍜⑤ 访问页面

在浏览器中使用 localhost:8080/HelloServlet/hello 来访问页面:

localhost:8080/HelloServlet/hello 

控制台会执行 service() 方法里的代码:

🌵四、Servlet 的运行原理

        在 Servlet 的代码中我们并没有写 main 方法,那么对应的 doGet 代码是如何被调用的呢?响应又是如何返回给浏览器的?

🦪1.当服务器接收到客户端浏览器的请求后,会解析请求的 URL 路径,获取访问的 Servlet 的资源路径。

🍣2.Tomcat 通过 Socket 读取到这个请求(一个字符串),会根据 url 中的 路径 判定这个请求 是 请求的一个静态资源还是动态资源。如果是静态资源,直接找到对应的文件把文件里的内容通过 Socket 返回。如果是动态资源,才会执行到 Servlet 的相关逻辑。

🍤3.Tomcat 会根据 url 中的 Context Path 和 Servlet Path 确定要调用哪个 Servlet 实例的方法

🌾五、Servlet 的生命周期

我们先来回顾一下我们上面代码里的 5 个方法:

方法名称功能/调用时机
init初始化方法,在 Servlet 实例化之后被调用一次,只会执行一次
getServletConfig获取 ServletConfig 对象,也就是 Servlet配置。(了解即可)
service提供服务的方法,每次服务器被访问时执行,可以执行多次
getServletInfo获取 ServletInfo 对象,也就是 Servlet的信息。(了解即可)
destory销毁方法,在 服务器 正常关闭时被调用,只会执行一次

        现在我们分别在 init() 、service() 、destory() 方法里加入 “System.out.println("执行 XXX 方法");”

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;

@WebServlet("/hello")
public class HelloServlet implements Servlet {
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("执行 init 方法");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("执行 service 方法");
    }

    @Override
    public String getServletInfo() {
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("执行 destroy 方法");
    }
}

来观察一下结果

当我们第一次访问 localhost:8080/HelloServlet/hello 的时候,控制台输出结果如下:

当我们多次访问这个网站时:

 

当我们关闭服务器的时候:

下面我们来通过上述现象来解析一下 Servlet 的生命周期:

🍦1.被创建:执行 init 方法,只执行一次

Servlet 什么时候被创建?

  • 默认情况下,第一次被访问时,Servlet 被创建
  • 也可以在服务器启动的时候进行创建,不过需要在 web.xml 进行配置(如果我们的 init()方法 要初始化的资源比较多,或者有其他的 Servlet 依赖这个 Servlet 的时候,可以在服务器启动的时候进行创建)

        Servlet 的 init()方法只执行一次,说明 Servlet 在内存中只存在一个对象,因此难免会出现多线程安全问题:比如 抢票 APP ,就涉及到许多的客户端对一个Servlet进行修改操作。

        那么我们应该尽量避免在 Servlet 中创建成员变量,及时创建了成员变量,也不要去修改它。

🍧2.提供服务:执行 service()方法,执行多次

        每次访问 Servlet 时,Service 方法都会被调用一次。

🍨3.被销毁:执行 destroy()方法,只执行一次

        Servlet 被销毁前执行(就像临终遗言)。只有服务器正常关闭,才会执行 destroy()方法。

小结:

        Servlet 是一种实现 动态页面 的技术,是一组 Tomcat 提供给程序员的 API。它的生命周期有 init、service、destroy,就像人的一生:出生、工作、死亡~~

        下一篇我们着重讲解 HttpServlet ~~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【力扣刷题 | 第十五天】

目录 前言&#xff1a; ​​​​​​​63. 不同路径 II - 力扣&#xff08;LeetCode&#xff09; 343. 整数拆分 - 力扣&#xff08;LeetCode&#xff09; 总结&#xff1a; 前言&#xff1a; 本篇我们主要刷动态规划的题&#xff0c;解题还是严格按照我们在【夜深人静写算法…

macOS Sonoma 14 beta 2 (23A5276g) Boot ISO 原版可引导镜像

macOS Sonoma 14 beta 2 (23A5276g) Boot ISO 原版可引导镜像 本站下载的 macOS 软件包&#xff0c;既可以拖拽到 Applications&#xff08;应用程序&#xff09;下直接安装&#xff0c;也可以制作启动 U 盘安装&#xff0c;或者在虚拟机中启动安装。另外也支持在 Windows 和 …

第4章 流程控制

第4章 流程控制 if else常规用法 单分支&#xff0c;双分支&#xff0c;多分支 带返回值 ​ scala实现java三元运算符 ​ for循环控制 基本语法 for ( 循环变量 <- 数据集 ) { 循环体} package chapter04import scala.language.postfixOpsobject Test02_ForLoop {def ma…

java的嵌套类(nested class)、内部类(inner class)的区别

嵌套类即nested class&#xff0c;内部类即Inner class。 概括来说&#xff0c;嵌套类的概念比内部类概念大。嵌套类包含内部类和非内部类。一个内部类一定是一个嵌套类&#xff0c;但一个嵌套类不一定是一个内部类。 在一个类内部或者接口内部声明的类是嵌套类。 下面这些类是…

php个人简历模板

php个人简历模板一 目前所在&#xff1a; 广州 年 龄&#xff1a; 31 户口所在&#xff1a; 汕头 国 籍&#xff1a; 中国 婚姻状况&#xff1a; 已婚 民 族&#xff1a; 汉族 身 高&#xff1a; 175 cm 体 重&#xff1a; 求职意向 人才类型&#xff1a; 普通求职 应聘职…

React封装axios请求

1、前言 因为最近在进行老系统用新框架改造&#xff0c;正好用到了react&#xff0c;就顺便整理了一下react中对axios进行封装的相关知识点和步骤。 2、如何封装 可以参考一下chat gpt给出的回答。 我大概总结一下&#xff0c;其实就是使用axios.create创建一个axios的实例&…

如何清除浏览器的 DNS 缓存 (Chrome, Firefox, Safari)

如何清除浏览器的 DNS 缓存 (Chrome, Firefox, Safari) Chrome Chromium Edge Firefox Safari clear DNS Cache, flush DNS cache 请访问原文链接&#xff1a;https://sysin.org/blog/clear-browser-dns-cache/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。…

设计模型学习-UML图

1&#xff0c;简介 UML图有很多种类型&#xff0c;但掌握其中的类图、用例图和时序图就可以完成大部分的工作。其中最重要的便是「类图」&#xff0c;它是面向对象建模中最常用和最重要的图&#xff0c;是定义其他图的基础。 类图主要是用来显示系统中的类、接口以及它们之间的…

Qt/C++编写手机版本视频播放器和Onvif工具(可云台和录像)

一、前言 用Qtffmpeg写播放器很多人有疑问&#xff0c;为何不用Qt自己的多媒体框架来写&#xff0c;最重要的原因是Qt自带的目前都依赖具体的本地解码器&#xff0c;如果解码器不支持&#xff0c;那就是歇菜的&#xff0c;最多支持个MP4格式&#xff0c;而且在手机上也都是支持…

音视频数据处理-H265/HEVC视频码流分析

一、H265概述 H265/HEVC&#xff08;Hight Efficiency Video Coding&#xff09;是由ITU-T和ISO/IEC两大组织在H264/AVC的基础之上推出的新一代高效视频编码标准&#xff0c;主要为应对高清和超高清视频在网络传输和数据存储方面带来的挑战。上一篇文章对H264/AVC视频码流进行…

python复习第一章

什么是 Python&#xff1f; Python 是一门流行的编程语言。它由 Guido van Rossum 创建&#xff0c;于 1991 年发布。 它用于&#xff1a; Web 开发&#xff08;服务器端&#xff09;软件开发数学系统脚本 Python 可以做什么&#xff1f; 可以在服务器上使用 Python 来创建…

【软件设计师暴击考点】下午题高频考点暴击系列

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;软件…

“前端已死”

一、一些迹象 逛社区&#xff0c;偶然看到了这张图片&#xff1a; 嗯……我眉头一皱&#xff0c;久久不语&#xff0c;心想&#xff0c;有这么夸张吗&#xff0c;假的吧&#xff1f; 突然想到&#xff0c;最近我在社区发了个前端招聘的信息&#xff0c;结果简历漫天纷飞&…

RK3568平台开发系列讲解(外设篇)四线风扇驱动实验

🚀返回专栏总目录 文章目录 一、硬件连接二、原理图分析三、驱动适配3.1、内核配置3.2、修改设备树3.3、实验沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将讲解四线风扇的使用。 一、硬件连接 风扇模块如下所示,黑线是负,红线是正,黄线是测速,蓝线是…

定时器的实现原理

文章目录 1.定时器的作用?2.数据结构要求3.时间轮4.分级时间轮5.业界实现方案参考文献 1.定时器的作用? 定时器的主要用途是执行定时任务。 定时任务在很多场景都需要用到&#xff0c;比如游戏的 Buff 实现&#xff0c;Redis 中的过期任务&#xff0c;Linux 中的定时任务&a…

【总结】yarn ResourceManager 宕机重启总是失败解决排查

目录 Yarn ResourceManager 莫名奇妙宕机重启Yarn ResourceManager 报错1重启Yarn ResourceManager 报错2成功解决 Yarn ResourceManager 莫名奇妙宕机 接到同事反馈&#xff0c;说yarn RM 端口总是访问超时。但是查看日志&#xff0c;又没有发现任务蛛丝马迹&#xff0c;且RM…

Redis的复制

配置 在Redis中使用复制功能非常容易 在从Redis服务器的redis.conf中写入slaveof masterip masterport即可&#xff0c;主Redis服务器不需要做任何配置在启动Redis服务器的时候&#xff0c;指定主服务器&#xff0c;redis-server --slaveof masterip masterport在客户端指定主…

如何评估大型语言模型(LLM)?

编者按&#xff1a;近期几乎每隔一段时间&#xff0c;就有新的大语言模型发布&#xff0c;但是当下仍然没有一个通用的标准来评估这些大型语言模型的质量&#xff0c;我们急需一个可靠的、综合的LLM评估框架。 本文说明了为什么我们需要一个全面的大模型评估框架&#xff0c;并…

C#TryCatch用法

前几天一个学员在学习C#与TryCatch用法时,也不知道TryCatch用法装可以用来做什么 。下面我们就详细讲讲C# 和封TryCatch用法相关知识。 C# 是一种通用、类型安全且面向对象的编程语言&#xff0c;由微软开发并在 .NET 平台上运行。TryCatch 是 C# 语言中的一个结构&#xff0c…

CSS的自定义属性var和JS的classList.toggle()方法,使用详细(css中var变量怎么应用)

简介&#xff1a;CSS中的var&#xff08;变量&#xff09;是CSS3中的新特性&#xff0c;用于定义可重用的值&#xff0c;类似于编程语言中的变量&#xff1b;它允许您在整个CSS文件中定义一个值&#xff0c;并在需要时使用该值。这样可以使CSS更加灵活和易于维护&#xff1b;cl…