Servlet (上篇)

news2024/9/26 3:24:50

哥几个来学 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 ~~

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

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

相关文章

client-go的Indexer三部曲之二:性能测试

欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)&#xff1a;https://github.com/zq2599/blog_demos 本篇概览 本文是《client-go的Indexer》系列的第二篇&#xff0c;在前文咱们通过实例掌握了client-go的Indexer的基本功能&#xff0c;本篇咱们尝试对下面这…

css小兔鲜项目搭建

目录 精灵图 精灵图的使用步骤 背景图片大小 background连写 文字阴影 盒子阴影 过渡 骨架标签 SEO三大标签 版心的介绍 css书写顺序 项目结构搭建 精灵图 场景&#xff1a;项目中将多张小图片&#xff0c;合并成一张大图片&#xff0c;这张大图片称之为精灵图 优点…

c语言实现 顺序存储和链式存储(几种链表)

目录 一、简介 二、一些问题 1、递归free 2、free单向循环链表&#xff1a; 3、free单向链表 4、free双向循环链表 5、free使用数组实现链式存储结构 6、sizeof&#xff08;&#xff09;求字符串大小的问题 三、总结 一、简介 花了几天的时间从头开始使用c语言…

UnityVR--UIManager--UI管理2

目录 前言 UIManger的实现 1. 需要用到的变量和数据 2. 在构造中的工作 3. 初始化面板 4. 显示面板 5. 隐藏面板和隐藏所有面板 6. 其他小工具 在场景中实现 1. 不同面板的类型设置 2. 场景中的设置 前言 接前篇&#xff0c;上一篇已经有了UITools.cs其中定义了UI面板需…

Web服务器群集:部署LAMP平台

目录 一、理论 1.LAMP平台 2.Apache网址服务基础 2.httpd服务器的基本配置 3.构建虚拟Web主机 4.MySQL服务 5.构建PHP运行环境 二、实验 1.LAMP架构DISCUZ论坛应用 三、问题 1.虚拟机内存分配上限问题&#xff0c;内存上限只能加到3G。 2.虚拟机CPU如何设置才更加合…

RISC-V 函数调用约定和Stack使用

RISC-V 函数调用约定和Stack使用 引言RISC-V vs x86RISC-V寄存器StackStruct补充函数调用约定寄存器约定函数跳转和返回指令的编程约定被调用函数的编程约定 RISC-V 汇编与 C 混合编程RISC-V 汇编调用 C 函数C 函数中嵌入 RISC-V 汇编 引言 MIT 6.S081 2020 操作系统 本文为M…

1744_Perl获取文件属性参数

全部学习汇总&#xff1a; GreyZhang/perl_basic: some perl basic learning notes. (github.com) 前阵子写通过Perl执行判断调用ImageMagick实现图像的批量压缩功能脚本时用到过这个功能&#xff0c;只是当时仅仅看了一个获取文件大小的功能。 今天看第六版的小骆驼书又看到了…

一篇十分硬核的QT开发经验文章!送给正在做QT开发或想从事QT开发的你

当编译发现大量错误的时候&#xff0c;从第一个看起&#xff0c;一个一个的解决&#xff0c;不要急着去看下一个错误&#xff0c;往往后面的错误都是由于前面的错误引起的&#xff0c;第一个解决后很可能都解决了。 定时器是个好东西&#xff0c;学会好使用它&#xff0c;有时…

别再为缓慢启动而失去用户! 让你的Android应用体验绝佳性能

为什么要启动优化&#xff1f; 启动优化是为了提升应用程序的启动性能&#xff0c;即减少应用程序从启动到可交互状态所需要的时间。以下是一些关键原因&#xff0c;解释了为什么启动优化是重要的&#xff1a; 用户体验&#xff1a; 启动时间是用户与应用程序互动的第一个体验…

常用API

文章目录 1、String类String概述创建对象的两种方式字符串的内容比较String常用APIString类开发验证码功能手机号码屏蔽功能 2、Object类Object类的作用Object类的常用方法**Object的toString方法**Object的equals方法 3、Objects类4、StringBuilder类5、Math类6、System类7、B…

2023-06-17:说一说redis中渐进式rehash?

2023-06-17&#xff1a;说一说redis中渐进式rehash&#xff1f; 答案2023-06-17&#xff1a; 在Redis中&#xff0c;如果哈希表的数组一直保持不变&#xff0c;就会增加哈希冲突的可能性&#xff0c;从而降低检索效率。为了解决这个问题&#xff0c;Redis会对数组进行扩容&am…

基于Spark的气象数据分析

研究背景与方案 1.1.研究背景 在大数据时代背景下&#xff0c;各行业数据的规模大幅度增加&#xff0c;数据类别日益复杂&#xff0c;给数据分析工作带来极大挑战。气象行业和人们的生活息息相关&#xff0c;随着信息时代的发展&#xff0c;大数据技术的出现为气象数据的发展…

第九章 形态学图像处理

文章目录 9形态学图像处理9.2腐蚀与膨胀9.2.1腐蚀9.2.2膨胀 9.3开操作和闭操作9.5一些基本形态学方法9.3.1边界提取 9.6灰度级形态学9.6.3一些基本的形态学算法 9形态学图像处理 9.2腐蚀与膨胀 9.2.1腐蚀 imgcv2.imread(dige.png,0) kernel np.ones((3,3),np.uint8) num[[…

第七章 原理篇:HOG特征提取

之前面试被问到了然后没有讲出来&#xff0c;所以今天复习一下&#xff01; 气死我了&#xff01; 参考教程&#xff1a; What Is a Feature Descriptor in Image Processing? https://medium.com/analytics-vidhya/a-gentle-introduction-into-the-histogram-of-oriented-…

scratch lenet(3): 直方图均衡化的C语言实现

文章目录 1. 目的2. 原理3. 实现3.1 获得直方图 int hist[256]3.2 获得累积分布 int cdf[256]3.3 均衡化公式3.4 遍历原图&#xff0c;逐点均衡化&#xff0c;得到结果 4. 完整代码和结果4.1 例子14.2 例子24.3 例子34.4 完整代码 5. References 1. 目的 用 C 语言实现直方图均…

低价618背后,看见品牌营销的「产业新洪流」

如今消费者对于低价与品质的兼得需求&#xff0c;正倒逼一个全新的产业经济模式出现&#xff0c;而企业恰是最直接承载者。只有具备真正“低价”的能力模型&#xff0c;企业才能参与到下一轮的产业经济&#xff0c;甚至是社会经济的发展浪潮中。 作者|皮爷 出品|产业家 成本不…

Elasticsearch设置密码

Elasticsearch设置密码 概述ES开启认证配置密码访问开启安全认证的EScurl浏览器直接访问Kibana 配置 es认证直接配置用户名密码到 kibana.yml以kibana密钥的形式使用命令行启动参数形式指定用户名密码 使用kibana 查看es用户 概述 ES默认没有开启安全组件&#xff0c;如果我们…

简单的Dubbo实验环境搭建

Dubbo-api中定义的UserQueryFacade接口可以发布在私服上&#xff0c;这样子dubbo-consumer和dubbo-provider就可以以maven依赖的形式导入使用。dubbo-provider需要提供接口的实现类&#xff0c;dubbo-consumer需要订阅该实现类&#xff0c;他们的元数据都通过zk进行记录。 许多…

Three.js学习项目--3D抗美援朝数据可视化

文章目录 部分场景体验地址操作说明 视频我做了哪些&#xff08;功能&#xff09;局限源代码地址部分逻辑按需渲染模型加载动画控制器模型纹理条件切换模型加载同时请求部分纹理 生成进度条模型缩放小动画 部分场景 体验地址 https://kmyc.hongbin.xyz/ 操作说明 视频 操作说…

LeetCode——查询后矩阵的和

目录 1、题目 2、题目解读 3、代码 1、题目 2718. 查询后矩阵的和 - 力扣&#xff08;Leetcode&#xff09; 给你一个整数 n 和一个下标从 0 开始的 二维数组 queries &#xff0c;其中 queries[i] [typei, indexi, vali] 。 一开始&#xff0c;给你一个下标从 0 开始的…