【浅学Java】Servlet详解

2023-10-27

1. 什么是Servlet

Servlet是TomCat提供给程序员的一组API,帮助程序员简单高效的开发一个Web app.

Servlet 主要做的工作:

  1. 允许程序猿注册一个类, 在 Tomcat 收到某个特定的 HTTP 请求的时候, 执行这个类中的一些代码.
  2. 帮助程序猿解析 HTTP 请求, 把 HTTP 请求从一个字符串解析成一个 HttpRequest 对象.
  3. 帮助程序猿构造 HTTP 响应. 程序猿只要给指定的 HttpResponse 对象填写一些属性字段, Servlet 就会自动的安装 HTTP 协议的方式构造出一个 HTTP 响应字符串, 并通过 Socket 写回给客户端.

2. 创建一个Servlet程序

1. 创建项目 (Maven)

new project ——> 选择Maven ,即可创建一个Maven项目

项目的目录结构:
在这里插入图片描述

2. 引入依赖

这里引入的依赖就是写Servlet程序需要的依赖(Servlet的 jar 包)。
之前在JDBC变成时,引入mysql的驱动包时手动导入,这里我们依赖maven来实现自动导入

  1. 在 https://mvnrepository.com/ 找到servlet,然后选择3.1.0版本
    在这里插入图片描述
  2. 选中这一串1内容,将其拷贝到pom.xml文件中
    在这里插入图片描述
    注意:第一次使用会有如下标红
    在这里插入图片描述
    一般会自动下载,如果没有自动下载,那就点击如下刷新按钮:
    在这里插入图片描述

3. 创建一些新目录

在这里插入图片描述

<!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>

4. 编写代码

  1. 创建HelloServlet,继承HttpServlet
    在这里插入图片描述
  2. 构造响应在这里插入图片描述
  3. 注意:
    在这里插入图片描述

5. 打包

在这里插入图片描述
此时打成的包是一个jar包,但是Tomcat只能识别war包,所以要打成war包。此时就得修改pom.xml,让打成的包是一个war包

<packaging>war</packaging>//打成war包
    <build>
        <finalName>hello_servlet</finalName>//打成的包名叫做hello_servlet
    </build>

此时就会形成一个war包:
在这里插入图片描述

6. 部署

将刚才打成的war包拷贝到Tomcat的webapp当中

  1. 打开war目录复制war
    在这里插入图片描述
  2. 粘贴到Tomcat的webapp,然后启动Tomcat

在这里插入图片描述

7. 验证程序

执行结果:
在这里插入图片描述
URL分析:
在这里插入图片描述

3. 简化创建Servlet的步骤

上述的7个步骤中,1 ~ 3在一个项目中操作一次就行了,而5 ~ 7在每次修改代码之后,都得进行一遍。所以,我们就从5 ~ 7入手进行简化。

1. 安装plugin插件——Smart Tomcat

Smart Tomcat的功能就是在idea中调用Tomcat。
安装之后,启动Tomcat就不需要找到Tomcat脚本来启动,直接在idea中就直接可以启动。

在这里插入图片描述
安装后进行重启。

2. Smart Tomcat的使用

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

4. Servlet API详解

1. HttpServlet

我们写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet, 并重写其中的某些方法.
在这里插入图片描述
我们实际开发的时候主要重写 doXXX 方法, 很少会重写 init / destory / service

1. 如何构造一个post请求

在前面,我们王浏览器中之家输入一个URL构造的都是get请求,下面我们看看怎么构造一个post请求:

  1. form表单(只支持get和post)
  2. ajax

这里我们采用ajax构造一个get请求:

  1. 创建一个html文件(注意文件目录的位置)
    在这里插入图片描述
  2. 写html代码
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<div>

</div>
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<script>
        $.ajax({
            type:'post',
            url:'hello',
            success:function(body){
                console.log(body);
            }
        });
     </script>
</body>>
</html>
  1. 测试请求
    在这里插入图片描述

2. 利用Postman构造请求

在这里插入图片描述

【面试】谈谈HttpServlet的生命周期

这个主要考查的就是啥时机调用啥方法

  1. 首次使用,先调用一次init
  2. 每次收到请求,调用service,在service内部通过方法来决定调用哪个doXXX
  3. 销毁之前调用destroy

2. HttpServletRequest

当 Tomcat 通过 Socket API 读取 HTTP 请求(字符串), 并且按照 HTTP 协议的格式把字符串解析成HttpServletRequest 对象.

1. 核心方法

在这里插入图片描述

2. 测试代码:

@WebServlet("/showRequest")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //调用一下RequestServlet里面的常用方法
        //把调用的结果显示到页面上
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(req.getProtocol());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getMethod());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getRequestURI());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getContextPath());
        stringBuilder.append("<br>");
        stringBuilder.append(req.getQueryString());
        stringBuilder.append("<br>");

        Enumeration<String> headerNames = req.getHeaderNames();
        while(headerNames.hasMoreElements()){
            String name=headerNames.nextElement();
            stringBuilder.append(name+":"+req.getHeader(name));
            stringBuilder.append("<br>");
        }

        resp.setContentType("text/html; charset=utf-8");//让浏览器知道body的数据格式是啥
        resp.getWriter().write(stringBuilder.toString());
    }
}

运行结果:
在这里插入图片描述

3. 注意事项:

在这里插入图片描述
2.在这里插入图片描述
两者之间的先后顺序不能乱

3. 传参的方式

1. 通过query string传参

@WebServlet("/studentInfo")
public class StudentInfoServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //假设客户端发来的请求形如:/studentInfo?studentId=104&studentId=20
        //就可以通过getParameter方法拿到两个Id的值
        String queryString = req.getQueryString();
        System.out.println(queryString);
        //getParameter方法的效果就是拿到queryString中的键值对
        String classId=req.getParameter("classId");
        String studentId=req.getParameter("studentId");
        System.out.println("classId: "+classId + " studentId: "+studentId);
        resp.getWriter().write("classId: "+classId + " studentId: "+studentId);
    }
}

运行结果:
在这里插入图片描述

2. 通过post请求的body传参(格式为x-www-from-urlencoded)

代码:

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html; charset=utf-8");
        //获取到body中的参数
        //约定 body 使用 application/x-www-from-urlencoded 这种格式来传参
        //这个格式就相当于calssId=104&studentId=20
        //这个格式和query string相同,只是数据在body中
        String classId = req.getParameter("calssId");
        String studentId = req.getParameter("studentId");
        System.out.println("classId: "+classId + " studentId: "+studentId);
        resp.getWriter().write("classId: "+classId + " studentId: "+studentId);
    }

postman构造post请求:
在这里插入图片描述
运行结果:
在这里插入图片描述

3. 利用form标签

创建文件:
在这里插入图片描述
代码展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>通过form构造请求</title>
</head>
<body>
    <form action="studentInfo" method="post">
        <input type="text" name="classId">
        <input type="text" name="studentId">
        <input type="submit" name="提交">
    </form>
</body>
</html>

浏览器访问:
在这里插入图片描述

利用fiddler抓包:
在这里插入图片描述

4. 构造JSON格式的HttpServletResponse

问题分析:
在这里插入图片描述
Jackson下载安装:

将下面得代码复制到pom.xml并刷新:

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.4.1</version>
</dependency>

核心代码(将json转换成字符串):

//这里属性得名字,应该与 json 的key保持一致
//这里的属性是public或者提供的public的getter方法
class Student{
    public int classId;
    public int studentId;
}
@Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理JSON格式的请求
        ObjectMapper objectMapper = new ObjectMapper();
        //从请求的body中进行读取,并解析
        //使用 readValue 来吧json字符串转称java对象
        //第一个参数是一个 String 或者是一个InputStream
        //第二个参数是转换的结果对应得 Java类对象
        Student student=objectMapper.readValue(req.getInputStream(),Student.class);
        System.out.println(student.classId+","+student.studentId);
        resp.getWriter().write(student.classId+","+student.studentId);
    }

运行结果:
在这里插入图片描述
方法总结:

objectMapper.readValue()——把json字符串转成java对象
objectMapper.writeValue()——把java对象转成json字符串

3. HttpServletResponse

0. HttpServletResponse的核心方法

在这里插入图片描述

1. 设置状态码

以404为例

@WebServlet("/status")
public class StatusCodeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setStatus(404);
    }
}

运行结果:
在这里插入图片描述
抓包结果:
在这里插入图片描述

2. 自动刷新

自动刷新就是给报文header设置Refresh属性,设置的value值就是N秒之后刷新。

@WebServlet("/refresh")
public class RefreshServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setHeader("Refresh","1");
        resp.getWriter().write(System.currentTimeMillis()+"");
    }
}

运行结果:
在这里插入图片描述
抓包结果:
在这里插入图片描述

3. 重定向

@WebServlet("/rediret")
public class RediretServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //约定跳转到搜狗主页
        resp.setStatus(302);
        resp.setHeader("Location","http://www.sogou.com");
    }
}

运行结果:在浏览器输入127.0.0.1:8080/hello_servlet/rediret
在这里插入图片描述
抓包结果:
在这里插入图片描述
提示,也可以这样,效果一样:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【浅学Java】Servlet详解 的相关文章

  • 如果测试用例失败,Selenium Web 驱动程序无法关闭 Firefox 实例

    我各位 我正在使用 junit 和 selenium web 驱动程序 2 28 问题是 如果我运行成功的测试用例 Web 驱动器能够关闭 Firefox 实例 但是当测试用例失败时 Selenium Web 驱动器无法关闭 Firefox
  • 如何在一行中将字符串数组转换为双精度数组

    我有一个字符串数组 String guaranteedOutput Arrays copyOf values values length String class 所有字符串值都是数字 数据应转换为Double QuestionJava 中
  • 在Windows上安装Java 11 OpenJDK(系统路径问题)

    Java 11 最近发布了 众所周知 这个版本没有安装文件 当然 要在没有安装程序的情况下安装 Java 我将系统设置 PATH 和 JAVA HOME 设置为解压缩 Java 11 的文件夹的地址 根据对类似问题的已接受回复建议 唯一的事
  • Android Studio 在编译时未检测到支持库

    由于 Android Studio 将成为 Android 开发的默认 IDE 因此我决定将现有项目迁移到 Android studio 中 项目结构似乎不同 我的项目中的文件夹层次结构如下 Complete Project gt idea
  • JNI 不满意链接错误

    我想创建一个简单的 JNI 层 我使用Visual studio 2008创建了一个dll Win 32控制台应用程序项目类型 带有DLL作为选项 当我调用本机方法时 出现此异常 Exception occurred during even
  • 如何查找 Android 设备中的所有文件并将它们放入列表中?

    我正在寻求帮助来列出 Android 外部存储设备中的所有文件 我想查找所有文件夹 包括主文件夹的子文件夹 有办法吗 我已经做了一个基本的工作 但我仍然没有得到想要的结果 这不起作用 这是我的代码 File files array file
  • Java8无符号算术

    据广泛报道 Java 8 具有对无符号整数的库支持 然而 似乎没有文章解释如何使用它以及有多少可能 有些函数 例如 Integer CompareUnsigned 很容易找到 并且似乎可以实现人们所期望的功能 但是 我什至无法编写一个简单的
  • 在浏览器中点击应用程序时播放框架挂起

    我正在 Play 中运行一个应用程序activator run 也许 5 次中有 3 次 它会挂起 当我去http localhost 9000 它就永远坐在那里旋转 我看到很多promise timed out错误也 我应该去哪里寻找这个
  • Java 页面爬行和解析之 Crawler4j 与 Jsoup

    我想获取页面的内容并提取其中的特定部分 据我所知 此类任务至少有两种解决方案 爬虫4j https github com yasserg crawler4j and Jsoup http jsoup org 它们都能够检索页面的内容并提取其
  • 请求位置更新参数

    这就是 requestLocationUpdates 的样子 我使用它的方式 requestLocationUpdates String provider long minTime float minDistance LocationLis
  • Clip 在 Java 中播放 WAV 文件时出现严重延迟

    我编写了一段代码来读取 WAV 文件 大小约为 80 mb 并播放该文件 问题是声音播放效果很差 极度滞后 你能告诉我有什么问题吗 这是我的代码 我称之为doPlayJframe 构造函数内的函数 private void doPlay f
  • Java中接口作为方法参数

    前几天去面试 被问到了这样的问题 问 反转链表 给出以下代码 public class ReverseList interface NodeList int getItem NodeList nextNode void reverse No
  • 检查 Android 手机上的方向

    如何查看Android手机是横屏还是竖屏 当前配置用于确定要检索的资源 可从资源中获取Configuration object getResources getConfiguration orientation 您可以通过查看其值来检查方向
  • 尝试使用 Ruby Java Bridge (RJB) gem 时出现错误“无法创建 Java VM”

    我正在尝试实现 Ruby Java Bridge RJB gem 来与 JVM 通信 以便我可以运行 Open NLP gem 我在 Windows 8 上安装并运行了 Java 所有迹象 至少我所知道的 都表明 Java 已安装并可运行
  • 应用程序关闭时的倒计时问题

    我制作了一个 CountDownTimer 代码 我希望 CountDownTimer 在完成时重新启动 即使应用程序已关闭 但它仅在应用程序正在运行或重新启动应用程序时重新启动 因此 如果我在倒计时为 00 10 分钟 秒 时关闭应用程序
  • Tomcat 6找不到mysql驱动

    这里有一个类似的问题 但关于类路径 ClassNotFoundException com mysql jdbc Driver https stackoverflow com questions 1585811 classnotfoundex
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • 当单元格内的 JComboBox 中有 ItemEvent 时,如何获取 CellRow

    我有一个 JTable 其中有一列包含 JComboBox 我有一个附加到 JComboBox 的 ItemListener 它会根据任何更改进行操作 但是 ItemListener 没有获取更改的 ComboBox 所在行的方法 当组合框
  • 运行 Jar 文件时出现问题

    我已将 java 项目编译成 Jar 文件 但运行它时遇到问题 当我跑步时 java jar myJar jar 我收到以下错误 Could not find the main class myClass 类文件不在 jar 的根目录中 因
  • 休眠以持久保存日期

    有没有办法告诉 Hibernate java util Date 应该持久保存 我需要这个来解决 MySQL 中缺少的毫秒分辨率问题 您能想到这种方法有什么缺点吗 您可以自己创建字段long 或者使用自定义的UserType 实施后User

随机推荐

  • kuka程序备份_KUKA机器人更改机器人名称及备份还原数据

    大家好 继之前发过的图文消息 连续好多期都是用视频讲解了 毕竟我觉得实际演示和语言沟通才是信息交流最通畅的方式 然而后台的播放数据并不好 半个小时的视频平均播放时长才十分钟 可能是视频太长了 我不是败给我自己 我是败给了这个时代 因为D音
  • 网络基础入门

    文章目录 一 网络的背景 独立模式 计算机之间相互独立 网络互联 多台计算机连接在一起 完成数据共享 局域网LAN和广域网WAN 二 网络在哪里 三 认识协议 四 OSI七层模型 五 TCP IP 四层模型 六 网络传输基本流程 七 数据包
  • mysqldump对mysql数据库的影响

    对于想入门或者初级 中级mysql数据库运维人员 了解mysqldump对mysql数据库的影响 是非常必要的 当执行mysqldump命令之后 mysql后台执行了什么 下面就带大家看看 在这里使用general log进行分析 1 首先
  • sql计算留存率

    文章目录 什么是留存率 案例1 案例2 案例3 案例4 参考 什么是留存率 留存用户是指用户在APP产生行为后 在固定的第N日继续访问或使用APP的用户 留存率是指用户在一段时间后或固定的间隔后产生留存用户的比例 用户留存率有很多种 新客留
  • 查看Linux服务器内存情况

    查看Linux服务器内存情况 一 free命令 二 top命令 总结 一 free命令 free命令用于显示内存的使用情况 包括实体内存 虚拟的交换文件内存 共享内存区段 以及系统核心使用的缓冲区等 语法 free bkmotV s lt
  • Redis 三台服务器搭建三主三从详细步骤

    1 需要三台服务器 如 服务器A B C 2 在三台服务器上安装gcc 执行如下命令 yum install gcc 3 验证是否安装好gcc gcc v 如果出现如下信息 代表已安装好 如果防火墙是开启状态 需要防火墙开通端口 永久开放如
  • CVPR 2023

    论文题目 Accelerated Coordinate Encoding Learning to Relocalize in Minutes using RGB and Poses 在公众号 3D视觉工坊 后台回复 原论文 可获取对应论文p
  • 血压计算法

    1 1 动脉平均压的计算 动脉平均压 MAP 是血压波 P t 形在一个周期内的积分除以周期T 其定义如下 均压反映了动脉血压的数值和波形 从试波法原理的两条基本原则 振荡波包络线呈现出近似抛物线的形态 脉搏振荡波振幅最大对应的袖带压力为平
  • 109,有序链表转换为二叉搜索树

    给定一个单链表 其中的元素按升序排序 将其转换为高度平衡的二叉搜索树 本题中 一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 示例 给定的有序链表 10 3 0 5 9 一个可能的答案是 0 3 9 10
  • css 小记

    新的 CSS 伪类函数 is 和 where is 旧的写法 h1 gt b h2 gt b h3 gt b h4 gt b h5 gt b h6 gt b color hotpink 新的写法 伪类 is is h1 h2 h3 h4 h
  • RSA算法多种生成公私钥的方式

    前言 在实际项目开发中常常需要用到非对称性加密算法生成公私钥应用于加密与认证 服务器间ssh免密等 关于非对称性加密算法生成公私钥等笔者之前有发表过一篇有趣的文章 感兴趣的朋友可以去了解下 生成公私钥的方式有很多 本文以RSA算法为例来讨论
  • 基于Matlab的跨孔CT胖射线追踪算法(二)

    基于Matlab的跨孔CT胖射线追踪算法 二 CT技术是一种无损的工程物探检测技术 因其方法简单 分辨率高 理论上更可靠 结果更直观 被广泛的应用于各种工程 胖射线追踪是CT技术的一种正演算法 本文的代码和示意图 供学习借鉴 1 文章目录
  • Java——JavaDoc生成文档

    JavaDoc javadoc命令是用来生成自己的APi文档 参数信息 author 作者名 version 版本号 since 致命需要最早使用的jdk版本 param 参数名 return 返回值情况 throws 异常抛出情况 用一段
  • pyecharts折线图上symbol(小圆圈)颜色的修改方法

    本人刚接触pyecharts 尝试做k线与指标图 但遇到不少困难 虽然pyecharts虽在展现上令人舒畅 但使用起来并不能像echarts那么完善 比如k线的颜色目前就改不了 我是在尝试了各种方法后 才在GitHub上找到了作者的回答 此
  • 截图 识别指定位置文字

    def tu browser get screenshot as file 1 png img Image open 1 png bo 图片左边到元素左边的距离 图片上面到元素上边的距离 图片左边到元素最右边的距离 图片上面到元素最下边的距
  • Keras—embedding嵌入层的使用

    最近在工作中进行了NLP的内容 使用的还是Keras中embedding的词嵌入来做的 Keras中embedding层做一下介绍 中文文档地址 https keras io zh layers embeddings 参数如下 其中参数重点
  • Flask 物联网局部应用情景

    实践 Raspberry Pi 托管 Flask 网络服务器控制设备 云托管 Flask 和 SQLite 网络服务器使用Web API 处理 ESP8266 数据 Raspberry Pi 托管 Flask 网络服务器使用SQLite存储
  • ChatGPT有哪些作用?

    ChatGPT有哪些作用 介绍 在当今信息技术飞速发展的时代 自然语言处理和人工智能已经成为许多领域的关键技术 ChatGPT是一种先进的语言生成模型 通过人工智能技术为用户提供了许多有用的功能和应用 本文将探讨ChatGPT的作用及其在不
  • 【ASP.NET Core】MVC模型绑定:自定义InputFormatter读取CSV内容

    Python微信订餐小程序课程视频 https edu csdn net course detail 36074 Python实战量化交易理财系统 https edu csdn net course detail 35475 在上一篇文章中
  • 【浅学Java】Servlet详解

    Servlet详解 1 什么是Servlet 2 创建一个Servlet程序 1 创建项目 Maven 2 引入依赖 3 创建一些新目录 4 编写代码 5 打包 6 部署 7 验证程序 3 简化创建Servlet的步骤 1 安装plugin