带你着手「Servlet」

news2024/11/23 18:27:42

在这里插入图片描述

请添加图片描述

⭐️前言⭐️

有了前边文章为我们奠定下的网络基础,我们就可以开始学习Servlet的知识了,在部署一个Java的Servlet程序时,必须要有的开发工具是Tomcat,需要自行完成Tomcat的配置,并掌握maven仓库的配置方法,下边我们也会进行演示,这些具体的流程该如何来进行。

🍉博客主页: 🍁【如风暖阳】🍁
🍉精品Java专栏【JavaSE】、【备战蓝桥】、【JavaEE初阶】、【MySQL】、【数据结构】
🍉欢迎点赞 👍 收藏留言评论 📝私信必回哟😁

🍉本文由 【如风暖阳】 原创,首发于 CSDN🙉

🍉博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言

🍉博客中涉及源码及博主日常练习代码均已上传码云(gitee)、GitHub


请添加图片描述

📍内容导读📍

  • 🍅1.第一个Servlet程序
    • 1.1 操作流程
    • 1.2 插件简化
  • 🍅2.常见的访问出错
    • 2.1 出现404
    • 2.2 出现405
    • 2.3 出现500
    • 2.4 出现空白页面
    • 2.5 出现“无法访问此网站”
  • 🍅3.Servlet运行原理
    • 3.1 Servlet运行原理
    • 3.2 Tomcat的执行逻辑

请添加图片描述

🍅1.第一个Servlet程序

我们首先通过idea来完成一个最简单的Servlet程序,共需要以下七步来完成,在该部分最后也会介绍较为简单的插件配置方法。

1.1 操作流程

第一步
创建一个maven项目。

1)新建项目
2ae400de2.png)

2)选择maven项目
在这里插入图片描述

3)编辑信息
在这里插入图片描述
第二步
引入依赖

1)在maven中央仓库找到Servlet的依赖
在这里插入图片描述
2)找到3.1版本,复制maven依赖
在这里插入图片描述
在这里插入图片描述
3)将依赖引入pom.xml文件中
在这里插入图片描述
第三步
创建目录结构

1)在main目录创建webapp目录
在这里插入图片描述
2)在webapp目录创建WEB-INF目录
在这里插入图片描述
3)在WEB-INF目录新建web.xml文件
在这里插入图片描述
4)在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>

在这里插入图片描述
第四步
编写Servlet代码

main-java目录下新建类,开始编写servlet代码
在这里插入图片描述

  • 继承HttpServlet
  • 重写doGet方法
  • 在方法里写执行的代码
  • 加上WebServlet注解+路径,将该类与http请求中的URL关联起来

在这里插入图片描述

第五步
打包

当前的代码是不能单独运行的(没有main方法),需要把当前的代码打包,然后部署到Tomcat上,由Tomcat来进行调用。

1)先进行准备工作,修改pom.xml
在这里插入图片描述
2)双击package,进行打包
在这里插入图片描述
打包完成
在这里插入图片描述
第六步
部署

1)打开war包所在路径
在这里插入图片描述
2)把war包拷贝到tomcatwebapps目录里
在这里插入图片描述

在这里插入图片描述
3)启动tomcat

在这里插入图片描述
在这里插入图片描述

第七步
验证程序

在网页访问路径127.0.0.1:8080/hello/test
在这里插入图片描述
此处的路径共有三部分组成
在这里插入图片描述

1.2 插件简化

在我们每次修改Servlet类代码后,都需要重复进行1.1中5-6步操作,较为繁琐,可以利用idea中内嵌的smart tomcat插件来简化开发流程。
在这里插入图片描述
完成上图插件的安装后,按下图流程操作。
在这里插入图片描述
注意,利用插件时,五六步操作完全不再需要手动进行了,不需要再进行第五步的准备工作——在pom.xml文件中加代码,直接在下图中定义Context Path即可。
在这里插入图片描述
点击小三角一次性完成打包、部署工作:在这里插入图片描述

🍅2.常见的访问出错

初学Servlet,肯定会遇到很多的问题,我们不仅要学习Servlet代码的基本写法,还需要认识常见的错误,在出现错误时能够解决。

2.1 出现404

404表示用户访问的资源不存在,大概率是URL路径写的不正确。
在这里插入图片描述
还有可能是因为web.xml文件写错了,需要写正确web.xml中内容,并重新启动tomact

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>

2.2 出现405

405表示对应的HTTP请求方法没有实现
在这里插入图片描述
在地址栏输入URL路径进行访问,浏览器默认构造的是GET请求,如果在服务器中的代码没有实现doGet方法,就会报这个错误。
在这里插入图片描述

在什么时候浏览器发的是GET请求呢?
1.直接在地址栏里输入URL
2.通过a标签跳转
3.通过img/link/script...
4.通过form表单,method指定为GET
5.通过ajax,type指定为GET

那在什么时候浏览器发的是POST请求呢?
1.通过form表单,method指定为POST
2.通过ajax,type指定为POST

2.3 出现500

500意味着服务器代码抛出异常了,并且代码没有处理异常,异常向上传递到了Tomcat这里了。
在这里插入图片描述
在这里插入图片描述
这种错误是最好解决的,因为异常的调用栈,会直接打印在页面上,可以直接找到问题的所在。

2.4 出现空白页面

没有resp.getWritter().write() 操作。
在这里插入图片描述

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

最大可能性是因为Tomcat没有正确启动(比如Tomcat的8080端口被占用,启动失败)
在这里插入图片描述

🍅3.Servlet运行原理

3.1 Servlet运行原理

Servlet是位于应用层的上层建筑,下面的传输层、网络层、和数据链路层属于经济基础,经济基础决定上层建筑。

Tomcat其实就是一个运行在用户态的应用程序(普通的Java进程)。
在这里插入图片描述
当用户操作浏览器,发送请求给服务器的时候,Tomcat作为HTTP Servlet会调用Servlet API,然后执行我们所写的Servlet程序来处理请求。
在这里插入图片描述
更详细的交互过程见下图:
在这里插入图片描述
用户浏览器发出请求后,客户端主机会将请求数据包一层层封装,最后到物理层转换成光电信号传输给服务器;到达服务器后再将数据包进行一层层分用,最后到服务器的应用层处理请求并计算响应

3.2 Tomcat的执行逻辑

我们通过用伪代码的方式来演示Tomcat在Servlet程序运行中起到的作用。

1)Tomcat初始化流程

class Tomcat {
    // 用来存储所有的 Servlet 对象
    private List<Servlet> instanceList = new ArrayList<>();
    public void start() {
        // 根据约定,读取 WEB-INF/web.xml 配置文件;
        // 并解析被 @WebServlet 注解修饰的类

        // 假定这个数组里就包含了我们解析到的所有被 @WebServlet 注解修饰的类. 
        Class<Servlet>[] allServletClasses = ...;

        // 这里要做的的是实例化出所有的 Servlet 对象出来;
        for (Class<Servlet> cls : allServletClasses) {
            // 这里是利用 java 中的反射特性做的
            // 实际上还得涉及一个类的加载问题,因为我们的类字节码文件,是按照约定的
            // 方式(全部在 WEB-INF/classes 文件夹下)存放的,所以 tomcat 内部是
            // 实现了一个自定义的类加载器(ClassLoader)用来负责这部分工作。

            Servlet ins = cls.newInstance();
            instanceList.add(ins);
        }

        // 调用每个 Servlet 对象的 init() 方法,这个方法在对象的生命中只会被调用这一次;
        for (Servlet ins : instanceList) {
            ins.init();
        }

        // 利用我们之前学过的知识,启动一个 HTTP 服务器
        // 并用线程池的方式分别处理每一个 Request
        ServerSocket serverSocket = new ServerSocket(8080);
        // 实际上 tomcat 不是用的固定线程池,这里只是为了说明情况
        ExecuteService pool = Executors.newFixedThreadPool(100);

        while (true) {
            Socket socket = ServerSocket.accept();
            // 每个请求都是用一个线程独立支持,这里体现了我们 Servlet 是运行在多线程环境下的
            pool.execute(new Runnable() {
                doHttpRequest(socket);//处理请求
            });
        }
        // 调用每个 Servlet 对象的 destroy() 方法,这个方法在对象的生命中只会被调用这一次;
        for (Servlet ins : instanceList) {
            ins.destroy();
        }
    }

    public static void main(String[] args) {
        new Tomcat().start();
    }
}

小结:

  • Tomcat的代码中内置了main方法。当我们启动Tomcat的时候,就是从Tomcat的main方法开始执行的。
  • @WebServlet注解修饰的类会在Tomcat启动的时候被获取到,并集中管理。
  • Tomcat通过反射机制来创建被@WebServlet注解修饰的类的实例。
  • 这些实例被创建完了之后,会调用其中的init方法进行初始化(该方法是HttpServlet自带的,我们自己写的类可以重写init)
  • 这些实例被销毁之前,会调用其中的destory方法进行收尾工作(只有正常退出Tomcat才会触发该方法,而通过直接杀死进程的方法是来不及调用该方法的)
  • Tomcat内部也是通过Socket API进行网络通信
  • Tomcat为了能同时响应多个HTTP请求,采取了多线程的方式实现。因此Servlet是运行在多线程环境下的

2)Tomcat处理请求流程

class Tomcat {
    void doHttpRequest(Socket socket) {
        // 参照我们之前学习的 HTTP 服务器类似的原理,进行 HTTP 协议的请求解析,和响应构建
        HttpServletRequest req = HttpServletRequest.parse(socket);
        HttpServletRequest resp = HttpServletRequest.build(socket);
        
        // 判断 URL 对应的文件是否可以直接在我们的根路径上找到对应的文件,如果找到,就是静态
        // 直接使用我们学习过的 IO 进行内容输出
        if (file.exists()) {
            // 返回静态内容
            return;
       }
        
        // 走到这里的逻辑都是动态内容了
        
        // 根据我们在配置中说的,按照 URL -> servlet-name -> Servlet 对象的链条
        // 最终找到要处理本次请求的 Servlet 对象
        Servlet ins = findInstance(req.getURL());
        
        // 调用 Servlet 对象的 service 方法
        // 这里就会最终调用到我们自己写的 HttpServlet 的子类里的方法了
        try {
       		ins.service(req, resp); 
       } catch (Exception e) {
            // 返回 500 页面,表示服务器内部错误
       }
   }
}

小结:

  • Tomcat从Socket中读取到HTTP请求,然后按照HTTP协议的格式解析成一个HttpServletRequest对象。
  • Tomcat会根据URL中的path判定这个请求是请求一个静态资源还是动态资源;如果是静态资源,直接找到对应的文件把文件的内容通过Socket返回;如果是动态资源,才会执行到Servlet的相关逻辑。
  • Tomcat会根据URL中的Context Path和Servlet Path确定要调用哪个Servlet实例的service方法(如果没有找到匹配的Servlet类,就会返回404)
  • 通过service方法,就会进一步调用到我们之前写的doGet或者doPost

3)Servlet的service方法的实现

class Servlet {
    public void service(HttpServletRequest req, HttpServletResponse resp) {
        String method = req.getMethod();
        if (method.equals("GET")) {
            doGet(req, resp);
       } else if (method.equals("POST")) {
            doPost(req, resp);
       } else if (method.equals("PUT")) {
            doPut(req, resp);
       } else if (method.equals("DELETE")) {
            doDelete(req, resp);
       } 
       ......
   }
}

小结:

  • Servlet的service方法内部会根据当前请求的方法,决定调用其中的某个doXXX方法。

在整个流程中,有三个关键的方法

  • init方法:在初始化阶段执行,用来初始化每一个Servlet对象,对象创建好之后就会执行到。用户可以重写这个方法,来执行一些初始化逻辑。
  • service方法:在处理请求阶段来调用,每个请求都要调用一次service
  • destory方法:退出主循环,tomcat结束之前会调用,用来释放资源。

⭐️最后的话⭐️
总结不易,希望uu们不要吝啬你们的👍哟(^U^)ノ~YO!!如有问题,欢迎评论区批评指正😁

请添加图片描述

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

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

相关文章

windows下搭建mindspore的编译环境

rugwindows 10下安装mindpsore环境&#xff0c;需要visual studio 2019及以上&#xff0c;cmake, python 也可以从上面下载mindspore编译依赖的软件。 visual studioan安装时需注意 然后再安装cmake,git&#xff0c;安装好之后设置检查环境变量&#xff0c;缺失的要补上 系统…

WEB静态网页设计与制作——我的美丽家乡邢台

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

【数据结构】顺序表OJ

文章目录0. 前言1. 移除元素2. 删除有序数组中的重复项3. 合并两个有序数组4. 结语0. 前言 在上篇博客中&#xff0c;我们使用C语言实现了顺序表。其中我们也对顺序表的接口进行了完整的实现。但是光实现不够&#xff0c;还是需要题目来练习。于是今天我就为大家带来顺序表的三…

【雷达仿真 | FMCW TDMA-MIMO毫米波雷达信号处理仿真(可修改为DDMA-MIMO)】

本文编辑&#xff1a;调皮哥的小助理 本文引用了CSDN雷达博主XXXiaojie的文章源码&#xff08;https://blog.csdn.net/Xiao_Jie1&#xff09;&#xff0c;加以修改和注释&#xff0c;全面地、详细地阐述了FMCW TDM-MIMO毫米波雷达的工作原理&#xff0c;同时配套MATLA仿真实现方…

kubernetes

目录 一、容器云发展及主要内容 1、云平台计算,交付标准&#xff08;iaas-----openstack&#xff09; 2、平台即服务(PAAS&#xff09; 3.软件及服务(SAAS) 特点 二、内容 三、kubernetes集群架构与组件 基本组件 (1)Pod&#xff08;最小的资源单位&#xff09; (2)初…

信息系统综合测试与管理__软件测试

一 概念 软件测试是使用人工或者自动手机来运行或测试某个系统的过程&#xff0c; 目的是检测是否满足需求或者比较预期与实际的差别。 软件测试应该覆盖整个开发、维护过程&#xff0c; 不仅仅是编码阶段完成之后进行的一项活动。 常考的软件测试工具为LoadRunner, 是一种…

RHCE——分区、创建逻辑卷

1.创建一个逻辑卷 请按下列要求创建一个新的逻辑卷&#xff1a; 创建一个名为 datastore 的卷组&#xff0c;卷组的大小为4G 逻辑卷的名字为 database ,所属卷组为 datastore,该逻辑卷大小为3G 将新建的逻辑卷格式化为 xfs 文件系统&#xff0c; 2.通过自动挂载将该逻辑卷到/v…

机器学习笔记 十五:随机森林(Random Forest)评估机器学习模型的特征重要性

随机森林1. 随机森林介绍1.1 租赁数据案例2. 特征相关性分析&#xff08;热图&#xff09;2.1 热图绘制2.2 构建随机森林模型2.3 不同特征合并的重要性2.3.1 经纬度合并&#xff08;分3类&#xff09;2.3.2 经纬度合并&#xff08;分2类&#xff09;2.3.3 经纬度合并&#xff0…

HTML CSS游戏官网网页模板 大学生游戏介绍网站毕业设计 DW游戏主题网页模板下载 游戏娱乐网页成品代码...

✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f947; 关于作者: 历任研发工程师&#xff0c;技术组长&#xff0c;教学总监。 十载寒冰&#xff0c;难凉热血&#xff1b;多年过去&#xff0c;历经变迁&#xff0c;物是人非。 然而&#xff0c;对于技术的探索…

系分 - 系统规划

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 系分 - 系统规划 考点摘要 系统规划的步骤&#xff08;★&#xff09;可行性分析&#xff08;★★★&#xff09;成本效益分析&#xff08;★★★&#xff09; 系统规划的步骤 初步调查根据企业战略目标&#…

一行行的代码解密马尔可夫链

使用Python的马尔科夫链实例的实践 一行行的代码解密马尔可夫链。 当我开始学习物理时&#xff0c;我并不喜欢概率的概念。我对用物理学可以对整个世界进行建模的想法非常振奋&#xff0c;不确定性的想法让我很生气:) 事实是&#xff0c;当我们想研究真实的现象时&#xff0c;我…

硬件电路(3)设计篇----为什么栅极型推挽电路不用上P下N?

在做信号控制以及驱动时&#xff0c;为了加快控制速度&#xff0c;经常要使用推挽电路。推挽电路可以由两种结构组成&#xff1a;分别是上P下N&#xff0c;以及上N下P。其原理图如下所示&#xff0c; 在平时中&#xff0c;我个人经常遇到的推挽电路是第一种。当我每次问身边的…

推荐一个不到2MB的C#开发工具箱,集成了上千个常用操作类

今天给大家推荐一个C#开发工具箱&#xff0c;涵盖了所有常用操作类&#xff0c;体积小、功能强大。 项目简介 C# 开发工具箱。大都是静态类&#xff0c;加密解密&#xff0c;反射操作&#xff0c;权重随机筛选算法&#xff0c;分布式短id&#xff0c;表达式树&#xff0c;lin…

单链表简单实现

单链表实现一、为什么会存在单链表&#xff1f;二、什么是单链表&#xff1f;三、单链表结构定义四、单链表的基本操作1、 创建结点2、 销毁链表3、 打印链表4、 尾插节点5、 头插结点6、 尾结点的删除7、 头结点的删除8、 单链表的查找9、 单链表在pos位置之后插入10、单链表在…

在jenkins上创建一个CANoe Job

目录实战项目CANoe 工程配置全局安全创建 slave 节点创建pipline Job&#xff1a; CANoeAutoRun实战项目CANoe 工程 配置全局安全 将代理和SSH Server都设置成随机选取&#xff0c;后面再本机创建slave 节点要用&#xff0c;因为我们会在用一台机器上创建了master和slave节点…

快充伤电池?我来帮何同学做个假设检验

最近看到何同学的视频&#xff0c;拿40部手机花两年半做了关于各种充电的实验视频&#xff0c;视频确实很好看&#xff0c;花里胡哨&#xff0c;看着科技感满满&#xff5e;。但是关于实验设计和根据实验的数据得出最后的结论上似乎有些草率。 实验设计上就不提了&#xff0c;…

周涛:在大数据沙滩上捡拾“珍珠”|奋斗者正青春

“我始终觉得&#xff0c;创新的本原就是好奇心&#xff0c;要像小孩儿一样&#xff0c;一直不断地追问&#xff0c;向这个世界讨要答案。在追寻答案的过程中&#xff0c;要有独立探索和批评的精神&#xff0c;不能轻信权威。” 1 提起电子科技大学教授周涛&#xff0c;大多…

【定语从句练习题】who、which

1. 填空训练 翻译的时候加上 … 的 1.who 2.which 3.which 4.which 5.who 6.which 7.which 8.who 9.who 10.which 11.which 12.who 2. 选择 1.took 2.live 3.she is 3.lost 5.bought 6.is parked 7.it cuts 8.writes 9.make 10.lent you. 10.lend sb. sth 这里需要&…

Java反射06:反射的应用之动态代理

反射的应用之动态代理 &#xff08;这里没听懂&#xff0c;知道反射体现了代理动态性就行&#xff0c;后面框架再学习&#xff09; 代理设计模式的原理 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象。任何对原 始对象的调用都要通过代理。代理对象决定是否以及何…

C语言之指针详解

文章目录1 指针1.1 简介1.2 什么是指针1.3 使用指针1.3.1 简单使用1.3.2 NULL 指针1.3.3 指针算术运算1.3.3.1 定义1.3.3.2 遍历数组&#xff1a;递增一个指针1.3.3.3 遍历数组&#xff1a;递减一个指针1.3.3.4 指针的比较1.3.4 指针数组1.3.5 指向数组的指针1.3.6 指向指针的指…