【Servlet】

news2024/11/25 4:00:52

目录

🎂1. 第一个 Servlet 程序:使用 Servlet 写 hello world

🥞1.1 创建项目

🍳1.2 引入依赖

🎃1.3 创建目录

🍘1.4 开始写代码

🌍1.5 打包代码

🍤1.6 部署

👑1.7 验证程序

🥗2. 简化上述 Servlet 程序

🚑3. Servlet 程序中常见问题

🌕3.1 404 

💎3.2 405 

🌝3.3 500 

💨3.4 出现“空白页面”

🎉3.5 出现“无法访问此网站”

🛸4.  Servlet API 

🐟4.1 init 方法

🦁4.2 destroy

🐸4.3 service 


新技术层出不穷,但是基础的东西、底层的东西,是不会变的,Servlet 。虽然工作中不大会直接使用 Servlet,但是学习 Servlet ,有助于我们学习其他更加成熟,更加方便的框架,比如(Sring、MVC)。

Servlet 是一种实现动态页面的技术。

动态页面 与 静态页面

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

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

静态网页,形如:

动态网页,类似于 B 站。

构建动态网页的技术有很多,每种语言都有一些相关的库/框架来做这件事。

Servlet 就是 Tomcat 这个 HTTP 服务器提供给 Java 的一组 API,来完成构建动态页面这个任务。

1. 第一个 Servlet 程序:使用 Servlet 写 hello world

需要经历七个固定步骤。

1.1 创建项目

在创建项目这一步里,需要用到 maven 这个构建工具。其功能是帮助我们构建、测试以及打包一个项目。

为什么需要 maven 呢?

作为新手程序员,已经习惯直接在 idea 里,点一下绿色的三角号来编译运行一个程序。这是因为这时候接触的程序比较简单。可是在公司的项目中,就会涉及很多个模块,这些模块存在依赖关系,比如运行先后的问题,甚至还可能依赖很多第三方库。因此就诞生了一系列的构造工具来解决上述问题。

Java 的构建工具有:Ant(老的构建工具)、Maven(当前比较主流的构建工具)以及 Gradle(更新的构建工具,目前主要是 Android 生态使用)。

创建一个 maven 项目:

打开一个 IDEA ,创建一个新项目:

首次使用 maven 项目,IDEA 会从互联网上加载很多的依赖,这需要一定的时间以及通畅的网络(maven 的服务器在国外)。

一个 maven 项目,首先得有一个 pom.xml 的配置文件:

1.2 引入依赖

jdk 里有很多内置的 api,比如 String、Thread、List/Map、Random、Scanner、InputStream/OutputSream。前面说了,Servlet 是 tomcat 提供的 api,但他不是标准库自带的,而是第三方库,需要额外下载安装 Servlet 的 jar 包。

去中央仓库搜索 Servlet :

 

选择哪个 servlet 版本下载呢?一定要与 tomacat 的版本相匹配才行。 3.1.0 与 tomcat 8.5 是相互匹配的。

除了可以直接点 jar下载之外,还可以借助 Maven 来下载。

将红框框住的代码复制粘贴,给 pom.xml 新增一个 <dependencies> 标签,里面可以放多个 dependency,用来引入多个第三方依赖。

只要把这一段代码往里一拷贝,IDEA 会自动调用 maven,从中央仓库下载该 jar 包。首次使用这里会标记成红色,一旦下载完成了,会变成白色。

打开 maven 面板,点击刷新按钮:

 这便安装成功了:

 jar 包是被下载到本地的一个隐藏目录中了:

1.3 创建目录

需要手动创建以下目录和文件:

这里的目录结构,目录位置,目录名字务必保证一字不错!

web.xml 是供 tomcat 使用的。tomcat 从 webapps 目录中加载 webapp,就是以 web.xml 为依据的。复制粘贴以下代码到 web.xml 中:

IDEA 对于 java 代码的识别是很准确的,红了就是有错,但对于其他的文件,就不一定了。所以上述代码标红了,不用太担心。

1.4 开始写代码

HttpServlet 这个类来自于从中央仓库下载的 jar 包。

重写父类中的 doGet 方法。

HTTP 请求:Tomcat 收到请求,把这个请求按照 HTTP 协议的格式,解析成一个对象。

HTTP 响应: 此处响应的对象,是一个空的对象。需要咱们在 doGet 中,设置响应的一些数据(比如响应的 body、header 以及状态码)。只要把属性设置到这个 resp 对象中,Tomcat 就会自动根据响应对象构造一个 HTTP 响应字符串,通过 socket 返回给客户端。

这个方法不是程序员手动调用的,而是 Tomcat 在合适的时机,自动调用。

以下是 Tomcat 的代码:

HttpServlet servlet = new HelloServlet();

......

// Tomcat 收到一个 HTTP 请求后,解析成 HttpServletRequest 对象

HttpServletRequest req = ...... ; //通过一系列的代码解析,按照 HTTP 协议的格式解析字符                                                       //串

HttpServletResponse resp = new HttpServletResponse(); //Tomcat 再创建一个空的属性,

                                                                                            //里面的属性还没有设置

servlet.doGet(req, resp); // Tomcat 调用执行 doGet 方法

                                        // doGet 根据 req 对象,结合业务逻辑,把 resp 生成出来

可以看出,程序员写的 doGet 是其中的一个部分,大部分环节都是现成的。这种代码的编写方式,便是框架(framework)。所谓框架,就是已经把绝大部分功能都写好了,不能随便乱写,只能按照人家的规范要求,写其中的一小段逻辑,把这段逻辑插入到整体的框架中。

super.doGet(req, resp),调用的是父类的 doGet 方法。点进 doGet 的父类方法:

发现父类的 doGet 会报错,405。所以在写自己的 doGet 方式时,要把 super.doGet(req, resp) 给删掉。

//给 HelloServlet 写注释
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 这是在 服务器的控制台中,打印了字符串
        System.out.println("hello world");
        // 这是在 resp 的 body 写入 hello world 字符串,这个内容就会被
        // HTTP 响应返回给浏览器,显示到浏览器页面上。
        resp.getWriter().write("hello world");
        //resp.getWriter 得到了 resp 内部特有的 Writer 对象,是一个字符流
    }
}

注解就是:

@xxxx

通常用来修饰一个类或者一个方法

最早认识的注解是

@Override

对于一个服务器程序来说,基本工作流程:

1. 读取请求并解析

2. 根据请求计算响应

3. 把响应写回给客户端

上述工作流程跟 UDP 和 TCP 回显服务器工作流程一样。1、3 已经被 Tomcat 完成了,只需要关注 2。

1.5 打包代码

上述程序,不能直接独立运行,而是必须放到 Tomcat 上运行,也就是部署。而部署的前提是先打包。

对于规模比较大的项目,里面会包含很多 .java 文件,进一步会产生很多的 .class ,所以把这些 .class 打成一个压缩包,再进行拷贝,比较好。

平时见到的压缩包,为 rar、zip等,在 java 中,使用的压缩包为 jar,war。普通的 Java 程序打包成 jar,而部署给 tomcat 的程序打包成 war。两者本质上没有区别,都是把一堆 .class 文件打包好。但 war 包是属于 tomcat 的专属格式,里面会有一些特定的目录结构和文件,比如 web.xml。后续 tomcat 要识别这些内容来加载 webapp。

打开 maven 控制面板,双击 package:

打包操作:

1. 检查代码中是否存在一些依赖,依赖是否安装好。(比如 servlet 依赖)

2. 把代码进行编译,生成一堆 .class 文件

3. 把这些 .class 文件以及 web.xml 按照一定的格式进行打包 

当前打的包是 jar 包,而不是 war 包。为了打出来 war 包,需要调整 pom.xml 。重新打开 pom.xml。

在 <\project> 标签上,写一个 <packing> 标签,描述打包的类型是 war:

 打出来的 war 包,起名为:

打好的 war 包,是一个普通的压缩包,可以使用压缩工具 (winrar) 打开。但并不需要手动解压缩,而是直接把整个 war 交给 tomcat ,tomcat 能自动解压缩。

1.6 部署

把打好的 war 包,拷贝到 tomcat 的 webapps 目录中。

 之后启动 Tomcat:

这个日志看着虽然乱码了,但是告诉我们,这个包已经部署成功了。

1.7 验证程序

不是 Tomcat 一启动,写的 doGet 就能执行。doGet 遇到 GET 请求,就会执行该方法。但也不是随便收到一个 GET 请求,就能执行 doGet,前提是,请求的 URL 的路径要匹配。

 

地址栏上的路径分为两级:

1. hello_servlet,称为 Context Path / Application Path,标识了一个 webapp,也就是这个 webapp 的目录名 / war 包名。(一个 Tomcat 上可以有多个 webapp,以此来表明用哪一个)

2. hello,称为 Servlet Path,标识当前请求要调用哪个 Servlet 类的 doGet。因为一个 webapp 中,可以有多个 Servlet ,自然就有多个 doGet 了。

2. 简化上述 Servlet 程序

重点简化 5 和 6,让 5 和 6 简化成一键式完成,需要借助 IDEA 的插件来完成这个工作。

首次使用 tomcat 需要配置一下:

 

如果我们的程序是拷贝 war 包到 webapps 中运行,此时 Context Path 是 war 包名字。如果我们的程序是使用 Smart Tomcat 运行,Context Path 是在上述配置中,手动设置的,默认是项目名字。

配置成功之后,IDEA 的右上角就出现了一个三角号按钮: 

以后运行代码就可以直接点击绿色三角号了。打包部署一键完成!

此时,tomcat 的日志就会在 IDEA 中显示了,不会再单独弹出 cmd,这样乱码的问题就解决了。虽然满屏幕都是红色,但不一定是错误的。

当我们使用 Tomcat 运行之后,再在 IDEA 中运行,就出现以下问题:

这是因为,启动 Tomcat 需要绑定两个端口号,8080(业务端口),8005(管理端口)。而一个端口号只能被一个进程绑定。

所以当我们把黑框框的服务器关掉之后,再次去运行 IDEA 之后,就不会出现这个问题了。

在日志的最后一行,可以看到一行蓝色的url:

可以看到的是,这个路径只有 Context Path,而没有 Servlet Path!点开之后一定是 404!

smart tomcat 的运行方式和之前拷贝到 webapps 中,存在本质区别。在运行 Tomcat 时,通过特定参数:

来指定 Tomcat 加载某个特定目录中的 webapp。所以上述过程,既不会打包,也不会拷贝。这是开发和调试阶段使用的方式,而如果是部署到生产环境,还是得打包,拷贝的方式。

3. Servlet 程序中常见问题

3.1 404 

表示用户访问的资源不存在,大概率是 URL 的路径写的不正确。

1. 请求的路径写错了,Context Path 和 Servlet Path 写对了吗?

2. 路径写对了,但是 war 包没有被正确加载。比如 web.xml 写错了,就会导致 war 包不能被正确加载;或者 如果有两个 Servlet 的 Servlet Path 相同,也会导致不能正确加载。

3.2 405 

1. 表示发送请求的方法,和代码不匹配,比如代码写的是 doPost,但你发的请求是 GET !

2. 虽然方法和代码匹配,但忘记干掉 super.doXXX 了

3.3 500 

这是最常见,也是最好解决的。500 意味着你的服务器代码抛出异常了!

3.4 出现“空白页面”

服务器没有返回任何数据。

3.5 出现“无法访问此网站”

一般是 Tomcat 启动失败了。

关掉 smart tomcat 之后,再刷新以下页面,就会出现以下错误:

 

4.  Servlet API 

Servlet API 有很多,重点掌握三个类即可!

1. HttpServlet

2. HttpServletRequest

3. HttpServletResponse

2 和 3 有啥属性,有啥方法,只要熟悉 HTTP 协议,就很清楚了。

写一个 Servlet 程序,都要继承这个 HttpServlet 类,也就是说,这个 HttpServlet 中都有啥方法:

方法名称调用时机
init在 HttpServlet 实例化之后被调用一次
destroy在 HttpServlet 实例不再使用时调用一次
service收到 HTTP 请求时调用
doGet收到 GET 请求时调用(由 service 方法调用)
doPost收到 POST 请求时调用(由 service 方法调用)
doPut/doDelete/doOptions/......收到其他请求时调用(由 service 方法调用)

4.1 init 方法

HttpServlet 被实例化之后,首次收到匹配请求时,会调用一次,使用这个方法来做一些初始化相关的工作。

//给 HelloServlet 写注释
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("执行 init");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 这是在 服务器的控制台中,打印了字符串
        System.out.println("hello world");
        // 这是在 resp 的 body 写入 hello world 字符串,这个内容就会被
        // HTTP 响应返回给浏览器,显示到浏览器页面上。
        resp.getWriter().write("hello world");
        //resp.getWriter 得到了 resp 内部特有的 Writer 对象,是一个字符流
    }
}

运行程序之后,控制台上并没有执行 init 方法。


上述红框中的请求,会触发 HelloServlet 类的 doGet 的执行,但在首次执行 doGet 之前,会先调用 init。后续多次请求,也只会执行 doGet 。

 

4.2 destroy

该方法是 webapp 被卸载/被销毁之前执行一次,用来做一些收尾工作。但这里并不建议大家使用 destroy。

1. 如果通过 8005 管理端口,来停止服务器,此时 destroy 能执行。

2. 如果直接杀死进程的方式来停止服务器,此时 destroy 执行不了。

而上述两种停止服务器的方式,在绝大多数情况下,方式 2 更多,这就让 destroy 派不上用场。

Tomcat 启动会使用两个端口:

1. 8080 业务端口,类似于于工作微信

2. 8005 管理端口,类似于生活微信


4.3 service 

每次收到路径匹配的请求,都会执行。doGet / doPost 其实是在 service 中调用。一般不会重写 service,只要重写 doXXX 就行了。

Servlet 的生命周期(面试题)

init 初始情况下调用一次

destroy 是结束之前调用一次

service 每次收到路径匹配的请求都调用一次

 

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

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

相关文章

如何在华为OD机试中获得满分?Java实现【获取最大软件版本号】一文详解!

✅创作者&#xff1a;陈书予 &#x1f389;个人主页&#xff1a;陈书予的个人主页 &#x1f341;陈书予的个人社区&#xff0c;欢迎你的加入: 陈书予的社区 &#x1f31f;专栏地址: Java华为OD机试真题&#xff08;2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

使用kotlin用回溯法解决电话号码的字母组合问题

17. 电话号码的字母组合 难度中等 2474 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#xff1a; 输入&#…

23种设计模式中之中介者模式(Mediator Pattern)

前言&#xff1a;大家好&#xff0c;我是小威&#xff0c;24届毕业生&#xff0c;在一家满意的公司实习。本篇文章将23种设计模式中的迭代器模式&#xff0c;此篇文章为一天学习一个设计模式系列文章&#xff0c;后面会分享其他模式知识。 如果文章有什么需要改进的地方还请大佬…

运维工程师面试总结(含答案)

运维工程师面试总结 原文链接&#xff1a;https://www.cuiliangblog.cn/detail/article/2 一、linux 1. linux系统启动流程 第一步&#xff1a;开机自检&#xff0c;加载BIOS第二步&#xff1a;读取&#xff2d;&#xff22;&#xff32;第三步&#xff1a;Boot Loader grub…

uni-app常用场景速查记录

记录一下uniapp开发过程中遇到的问题场景,方便后期查看. 1.elementUI中textarea文本如何设置换行显示 2.uniapp中实现文字滚动显示 3.下拉刷新和触底分页查询 1.elementUI中textarea文本设置换行显示 el-input标签中type为textarea中录入的文本内容,在表格中显示…

关键词搜索1688商品数据采集、1688商品列表数据接口

1688&#xff1a;指中国最大的电子商务综合平台&#xff0c;类似于美国的亚马逊。 关键词&#xff1a;是用于描述检索文档或记录的词语或短语&#xff0c;通常是用户输入的查询信息。 搜索&#xff1a;是在数据库、网页搜索引擎或其他信息存储库中查找信息内容的过程。 商品数…

springboot+springsecurity+jwt+elementui图书管理系统

​​图书管理系统​​ 关注公号&#xff1a;java大师&#xff0c;回复“图书”&#xff0c;获取源码 一、springboot后台 1、mybatis-plus整合 1.1添加pom.xml <!--mp逆向工程 --><dependency><groupId>org.projectlombok</groupId><artifactId&…

腾讯云服务器可用区是什么意思?可用区详细说明

腾讯云服务器可用区什么意思&#xff1f;可用区&#xff08;Zone&#xff09;是指腾讯云在同一地域内电力和网络互相独立的物理数据中心&#xff0c;一个可用区故障不会影响另一个可用区的正常运行&#xff0c;所以可用区用于构建高容灾、高可靠性应用。腾讯云服务器网来详细说…

华为OD机试真题B卷 Java 实现【食堂供餐】,附详细解题思路

一、题目描述 某公司员工食堂以盒饭的方式供餐。 为将员工取餐排队时间降为0&#xff0c;食堂的供餐速度必须要足够快。 现在需要根据以往员工取餐的统计信息&#xff0c;计算出一个刚好能达到排队时间为0的最低供餐速度。 即&#xff0c;食堂在每个单位时间内必须至少做出…

分布式事务的21种武器 - 7

在分布式系统中&#xff0c;事务的处理分布在不同组件、服务中&#xff0c;因此分布式事务的ACID保障面临着一些特殊难点。本系列文章介绍了21种分布式事务设计模式&#xff0c;并分析其实现原理和优缺点&#xff0c;在面对具体分布式事务问题时&#xff0c;可以选择合适的模式…

Rocketmq学习之路(一)从生产上的问题引出MQ

前言&#xff1a; 从来没有真正弄明白mq是什么&#xff0c;只知道他有消峰&#xff0c;异步&#xff0c;解耦的作用。但是在日常开发工作中&#xff0c;就是简单的生产者发送消息&#xff0c;消费者接受消息。所以&#xff0c;从今天开始。我要吃掉这个技术。 一.这该死的订单…

word解决文字与公式mathtype不对齐

修改字体和段落里面的这两个。

每日学术速递5.23

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CL 1.Tree of Thoughts: Deliberate Problem Solving with Large Language Models 标题&#xff1a;思想树&#xff1a;用大型语言模型有意识地解决问题 作者&#xff1a;Shunyu Yao, …

每日学术速递5.24

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Reprompting: Automated Chain-of-Thought Prompt Inference Through Gibbs Sampling 标题&#xff1a;重新提示&#xff1a;通过 Gibbs 采样的自动思维链提示推理 作者&#xff1…

《java核心卷Ⅰ》读书笔记

&#x1f6eb; JDK和JRE傻傻分不清?&#x1f6eb; HelloWorld的输出都经历了啥&#xff1f;&#x1f6eb; Java的三个版本都是啥&#xff1f;&#x1f6eb; 关于main方法你都知道啥&#xff1f;main方法被声明为private会怎样&#xff1f;&#x1f6eb; 强制and自动类型转换都…

数据结构基础内容-----第四章 栈与队列

文章目录 栈栈的定义站的抽象数据类型两栈共享空间栈的作用递归的定义 栈运算 队列循环队列队列链式存储结构及实现 栈 栈的定义 栈&#xff08;Stack&#xff09;是计算机科学中的一种抽象数据类型&#xff0c;它是一个只能在一端进行插入和删除操作的线性数据结构。栈按照后…

tomcat what

tomcat是什么 对于tomcat是什么有什么作用。曾经看到一个大神是这样解释tomcat的&#xff0c;现在分享给大家 内容大体是&#xff1a; 我家有一台机器&#xff0c;可以把石头变成金子。你快递给我一箱石头&#xff0c;让我把它们变成一箱金子再快递给你。 这个机器就是web项…

【Python从入门到进阶】21、爬虫相关概念介绍

接上篇《20、HTML页面结构的介绍》 上一篇我们正式进入了Python爬虫的实战教程&#xff0c;主要讲解了要爬取的HTML页面的结构。本篇我们来介绍爬虫的相关概念。 一、什么是互联网爬虫 如果我们把互联网比作一张大的蜘蛛网&#xff0c;那一台计算机上的数据便是蜘蛛网上的一个…

如何自己搭建chatgpt镜像网站

前沿 总所周知&#xff0c;访问以及注册chatgpt都是比较困难的&#xff0c;如何能畅游chatgpt而不受魔法的限制呢&#xff1f;还好openai给出了非常不错的api能使我们快速搭建一个镜像网站 准备工作 首先得准备一台服务器 这里推荐使用海外vps来进行搭建&#xff0c;缺点就是…

java基础入门-16-【阶段项目(综合练习doudizhu游戏)】

Java基础入门-16-【阶段项目(综合练习&doudizhu游戏)】 25、阶段项目(综合练习&doudizhu游戏)斗地主小游戏斗地主游戏1(控制台版)步骤一:准备牌步骤二:洗牌步骤三:发牌步骤四:看牌步骤五:给牌进行排序(两种方式排序)方式一:利用序号进行排序方式二:给每一…