Tomcat Servlet

Tomcat & Servlet

  • 一、What is “Tomcat”?
  • 二、 What is “Servlet”?
    • 1、HttpServlet
    • 2、HttpServletRequest
    • 3、HttpServletResponse

一、What is “Tomcat”?

Tomcat 本质上是一个基于 TCP 协议的 HTTP 服务器。我们知道HTTP是一种应用层协议,是 HTTP 客户端和 HTTP 服务器之间的交互数据的格式。Tomcat 就是基于 Java 实现的一个开源免费,也是被广泛使用的 HTTP 服务器。

以下是 Tomcat 安装完成后的文件目录:

运行Tomcat我们可以使用cmd命令查看Tomcat的端口号的进程ID:


二、 What is “Servlet”?

对于网站的后端开发,我们总是围绕着 HTTP 服务器展开相关工作,当然我们也可以重 0 开始写一个服务器,一步步的实现服务器的功能,包括根据 HTTP 协议解析请求报文、根据HTTP构造响应报文等等……对于服务器来说,很多功能都是千篇一律的,如果我们把中心放到整个服务器的开发上,这对于业务逻辑的开发来说,显然是非常不友好的。因此我们可以借助现成的 HTTP 服务器进行开发,例如 Tomcat 就为我们省去了这些不必要的环节,为我们提供了一些列的 API ,让我们能够更专注于业务逻辑。

Servlet 就是一组 Tomcat 提供的 API,让程序猿自己写的代码能很好的和 Tomcat 配合起来,从而更简单的实现一个 webapp,而不必关注 Socket、HTTP协议格式、多线程并发等技术细节,降低了 webapp 的开发门槛,提高了开发效率。

Servlet 中提供的 API 有很多,这里我们重点掌握 3 个类:HttpServletHttpServletRequestHttpServletResponse,下面我们逐一介绍👇:

1、HttpServlet

我们写 Servlet 代码的时候,首先第一步就是先创建类,继承自 HttpServlet,并重写其中的某些方法。

HttpServlet 核心方法展示:

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

其中 init、destroy、service 这 3 个方法的调用时机,就称为 “Servlet 生命周期”:

  1. init方法,只会在初始情况下调用1次,也就是HttpServlet实例化时调用,一般使用这个方法做一些初始化的相关工作。(HttpServlet 的实例只是在程序启动时创建一次,而不是每次收到 HTTP 请求都重新创建实例。)
  2. destroy方法,用于该webapp被销毁之前执行1次,用来做一些首尾工作。但是并不建议使用这个方法,因为通常采用直接杀死进程的方式停止服务器,此时destroy执行不了。
  3. service方法,每次收到路径匹配的请求都会执行,例如上述doGet、doPost方法其实都是在service方法中被调用,一般不会重写service方法。

在实际开发中,我们往往重写 doXXX 方法,很少会重写 init / destory / service:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("hello world");}
}

代码说明:

  1. 在这个类上方加上 @WebServlet("/hello") 注解, 表示 Tomcat 收到的请求中, 路径为 /hello的请求才会调用HelloServlet 这个类的代码

  2. HttpServletRequest 表示 HTTP 请求。Tomcat 按照 HTTP 请求的格式把 字符串 格式的请求转成了一个 HttpServletRequest 对象。后续想获取请求中的信息(方法、url、 header、body 等) 都是通过这个对象来获取。

  3. HttpServletResponse 表示 HTTP 响应。我们可以根据resp响应对象提供的方法,构造响应的状态码, header, body 等。Tomcat 会把整个响应转成字符串,通过 socket 写回给浏览器。

2、HttpServletRequest

当 Tomcat 通过 Socket API 读取到 HTTP 请求(字符串)后,就会按照 HTTP 协议的格式把字符串解析成 HttpServletRequest 对象。

HttpServletRequest 提供了一些方法,可以获取到一个请求中的各个方面的信息:

HttpServletRequest 提供的方法都只是“读”方法,而不是“写”方法。其实这也很容易理解,请求对象是服务器收到的内容,不应该被修改。

方法描述
String getProtocol()返回请求协议的名称和版本。
String getMethod()返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
StringBuffer getRequestURL()它用于获取请求的URL,不包含 query string
String getRequestURI()它用于获取请求的统一资源标识符(URI)的部分,即资源路径。
String getContextPath()获取请求的ContextPath,ContextPath标识一个webapp,即webapp的目录名
String getServlettPath()获取请求的ServletPath,ServletPath标识一个类
String getQueryString()返回包含在路径后的请求 URL 中的查询字符串。
Enumeration getHeaderNames()返回一个枚举,包含该请求中包含的所有请求头名。
String getHeader(String name)以字符串形式返回指定请求头的值。
String getCharacterEncoding()返回请求主体中使用的字符编码的名称。
String getContentType()返回请求主体的类型,如果不知道类型则返回 null。
int getContentLength()以字节为单位返回请求主体的长度,如果长度未知则返回 -1。
InputStream getInputStream()返回一个 InputStream 对象,用于读取请求的 body 内容。

上面这些方法只要对HTTP协议足够了解,简单看一下就能够使用。这里主要介绍有关getParameter相关的方法:

方法描述
Enumeration getParameterNames()返回一个枚举,表示在该请求中包含的参数的名称。
String getParameter(String name)返回请求参数的值,以字符串形式返回,如果参数不存在则返回 null。
String[] getParameterValues(String name)返回一个字符串数组,表示给定请求参数的所有值,如果参数不存在则返回 null。

这些方法主要是获取请求中的请求信息的,下面以getParameter()为例:

1. 获取GET请求中的参数值

@WebServlet("/getParameter")
public class Test extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {// 前端通过 url 的 query string 传递 username 和 password 两个属性.String userName = req.getParameter("username");String passWord = req.getParameter("password");resp.setContentType("text/html; charset=utf-8");resp.getWriter().write("username="+userName+"<br/>"+"password="+passWord);}
}

2. 获取POST请求中的参数值

(1)请求参数通过body传递,采用 form 表单格式提交,即 Content-Type 是 application/x-www-form-urlencoded
此时同样可以使用getParameter直接获取参数值:

注意:需要显示地告诉后端请求的编码方式,防止解析请求时出现中文乱码情况。

@WebServlet("/postParameter")
public class Test extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {// 显示地告诉后端请求的编码方式,防止中文乱码req.setCharacterEncoding("utf8");// 前端通过 url 的 query string 传递 username 和 password 两个属性.String userName = req.getParameter("username");String passWord = req.getParameter("password");resp.setContentType("text/html; charset=utf-8");resp.getWriter().write("username="+userName+"<br/>"+"password="+passWord);}
}

(2)请求参数通过body传递,Content-Type 是 application/json

对于Servlet,其没有内置 json 的解析功能,此时想要获取这种格式的参数就需要借助第三方库 jackson,首先我们在中央仓库找到 jackson 依赖引入到 pom.xml 中,然后就可以编写解析 json 格式请求参数的代码了。

使用 jackson,最核心的对象就是 ObjectMapper,通过这个对象里面的两个方法,就可以把 json 字符串解析成 java 对象;也可以把一个 java 对象转成一个 json 格式字符串,具体如下:

  1. writeValueAsString 方法把一个 Java 对象转成 JSON 格式字符串。
  2. readValue方法, 第一个参数为输入流对象,或Json字符串,的第二个参数为 JsonData 的 类对象,通过这个类对象,在 readValue 的内部就可以借助反射机制来构造出 Java 对象。
class User {public String username;public String password;@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", password='" + password + '\'' +'}';}
}@WebServlet("/jsonParameter")
public class Test extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {// 设置响应格式resp.setContentType("text/html;charset=utf-8");// 通过 post 请求的 body 传递过来一个 json 格式的字符串.// 1.使用objectMapper将json字符串解析成java对象User user = objectMapper.readValue(req.getInputStream(), User.class);resp.getWriter().write("1.使用objectMapper将json字符串解析成java对象:<br/>"+user.toString()+"<br/>");// 2.使用objectMapper将java对象解析成json字符串String jsonString = objectMapper.writeValueAsString(user);resp.getWriter().write("2.使用objectMapper将java对象解析成json字符串:<br/>"+jsonString);}
}

3、HttpServletResponse

Servlet 中的 doXXX 方法的目的就是根据请求计算得到响应,然后把响应的数据设置到 HttpServletResponse 对象中,Tomcat 内壁就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式,转成一个字符串,并通过 Socket 写回给浏览器。

响应对象是服务器要返回给浏览器的内容,这里的重要信息都是程序员根据请求设置到响应中的,因此下面的方法都是 “写” 方法。

下面是在设置响应时常用到的方法:

方法描述
void setStatus(int sc)为该响应设置状态码。
void setHeader(String name, String value`设置一个带有给定的名称和值的 header。如果 name 已经存在,则覆盖旧的值。
void addHeader(String name, String value)添加一个带有给定的名称和值的 header。如果 name 已经存在,不覆盖旧的值,并列添加新的键值对。
void setContentType(String type)设置被发送到客户端的响应的内容类型。
void setCharacterEncoding(String charset)设置被发送到客户端的响应的字符编码(MIME 字符集),例如 UTF-8。
void sendRedirect(String location)使用指定的重定向位置 URL 发送临时重定向响应到客户端。
PrintWriter getWriter()用于往 body 中写入文本格式数据。
OutputStream getOutputStream()用于往 body 中写入二进制格式数据。

其实上面这些方法和同样只要对HTTP协议足够了解,简单看一下就能够使用,下面就简单演示几个方法,体会一下设置响应的过程:

(1)设置自动刷新

@WebServlet("/Refresh")
public class Refresh extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {// 设置自动刷新,刷新频率:每隔1秒自动刷新一次resp.setHeader("Refresh","1");resp.getWriter().write("time = "+System.currentTimeMillis());}
}

(2)设置重定向
方式1:使用 sendRedirect 方法

@WebServlet("/Redirect")
public class Redirect extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {// 设置重定向:resp.sendRedirect("https://www.baidu.com");}
}

方式1:使用 setStatus + setHeader方法

@WebServlet("/Redirect")
public class Redirect extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {// 设置重定向:resp.setStatus(302);resp.setHeader("Location","https://www.baidu.com");}
}

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

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

相关文章

(四)动态阈值分割

文章目录 一、基本概念二、实例解析 一、基本概念 基于局部阈值分割的dyn_threshold()算子&#xff0c;适用于一些无法用单一灰度进行分割的情况&#xff0c;如背景比较复杂&#xff0c;有的部分比前景目标亮&#xff0c;或者有的部分比前景目标暗&#xff1b;又比如前景目标包…

计算机网络笔记 第一章 概述

课程链接 https://www.bilibili.com/video/BV1c4411d7jb/?spm_id_from333.337.search-card.all.click 1.2 因特网概述 网络、互联网与因特网的区别与关系 若干节点和链路互相形成网络若干网络通过路由器互联形成互联网因特网是当今世界上最大的互联网 我们有时并没有严格区…

【mysql】—— 复合查询

前言&#xff1a; 在前面我已经讲解的mysql表的查询都是对一张表进行查询&#xff0c;在实际开发中这远远不够。因此&#xff0c;本期我将带大家学习的是关于 “ 复合查询” 的相关知识&#xff01;&#xff01;&#xff01; 目录 &#xff08;一&#xff09;基本查询回顾 &a…

【Java 进阶篇】JDBC ResultSet 遍历结果集详解

在Java数据库编程中&#xff0c;经常需要执行SQL查询并处理查询结果。ResultSet&#xff08;结果集&#xff09;是Java JDBC中用于表示查询结果的关键类之一。通过遍历ResultSet&#xff0c;我们可以访问和操作从数据库中检索的数据。本文将详细介绍如何使用JDBC来遍历ResultSe…

SpringCloud Alibaba - Sentinel 限流规则(案例 + JMeter 测试分析)

目录 一、Sentinel 限流规则 1.1、簇点链路 1.2、流控模式 1.2.1、直接流控模式 1.2.2、关联流控模式 a&#xff09;在 OrderController 中新建两个端点. b&#xff09;在 Sentinel 控制台中对订单查询端点进行流控 c&#xff09;使用 JMeter 进行测试 d&#xff09;分…

10个与AI相关的技术领域

**10个与AI相关的技术领域** 除了与各个科学领域相关的具体挑战之外&#xff0c;AI在科学领域还存在一些共同的技术挑战。特别是&#xff0c;我们确定了以下四个共同的技术挑战&#xff1a;超出分布的泛化、可解释性、由自监督学习提供支持的基础模型和不确定性量化。尽管这些…

手把手教你做个智能加湿器(一)

一、前言 目前常见的加湿器类电子产品一般是由PCBA和外壳组成&#xff0c;我们将从PCB设计&#xff0c;然后编写软件&#xff0c;接着设计外壳&#xff0c;设计出一个完整的产品出来。 需要使用到软件&#xff1a; Altium Designer 17 SolidWorks 2019 Keil 4 二…

实用调试技巧

引言&#xff1a;一个完美的代码离不开程序员的调试&#xff0c;所谓三分编写七分调试&#xff0c;今天我们给大家介绍几种实用的调试技巧。 1️⃣Bug的由来&#xff1a; 原意是指&#xff0c;小虫子&#xff0c;昆虫等&#xff0c;而人们也通常将电脑程序中的一些隐藏的缺陷或…

JavaSE学习之--抽象类,接口,内部类

&#x1f495;"没有眼泪我们就会迷路&#xff0c;彻底变成石头&#xff0c;我们的心会变成冰凌&#xff0c;吻会变成冰块。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;JavaSE学习之--抽象类&#xff0c;接口&#xff0c;内部类 目录 一.抽象…

机器学习---BP算法

1. 多级网络 层号确定层的高低&#xff1a;层号较小者&#xff0c;层次较低&#xff0c;层号较大者&#xff0c;层次较高。 输入层&#xff1a;被记作第0层。该层负责接收来自网络外部的信息。 第j层&#xff1a;第j-1层的直接后继层&#xff08;j>0&#xff09;&#xff…

奥斯卡·王尔德

奥斯卡王尔德 奥斯卡王尔德&#xff08;Oscar Wilde&#xff0c;1854年10月16日—1900年11月30日&#xff09;&#xff0c;出生于爱尔兰都柏林&#xff0c;19世纪英国&#xff08;准确来讲是爱尔兰&#xff0c;但是当时由英国统治&#xff09;最伟大的作家与艺术家之一&#xf…

27-动态代理和反射

参考视频链接 反射黑马教程 反射 反射初识 反射允许对封装类的字段&#xff0c;方法和构造函数的信息进行编程访问 它可以将一个类里面的方法和成员变量获取出来 反射是通过 class 文件中获取这字段&#xff0c;构造方法和成员方法&#xff0c;然后在从这三个当中进行解剖&…

燃气安全如何保障?万宾燃气管网监测系统时刻感知管网运行态势

近年来随着我国城镇化建设的加快&#xff0c;燃气已经成为每个家庭的必需品。然而&#xff0c;每年夏季频繁发生的燃气爆炸事故&#xff0c;已经严重危害人民生命财产安全危害社会公共安全和公共利益。为了保障燃气安全运行&#xff0c;近日&#xff0c;许多城市都在大力推进燃…

贪心算法+练习

正值国庆之际&#xff0c;祝愿祖国繁荣昌盛&#xff0c;祝愿朋友一生平安&#xff01;终身学习&#xff0c;奋斗不息&#xff01; 目录 1.贪心算法简介 2.贪心算法的特点 3.如何学习贪心算法 题目练习&#xff08;持续更新&#xff09; 1.柠檬水找零&#xff08;easy&…

最新AI智能问答系统源码/AI绘画系统源码/支持GPT联网提问/Prompt应用+支持国内AI提问模型

一、AI创作系统 SparkAi创作系统是基于国外很火的ChatGPT进行开发的AI智能问答系统和AI绘画系统。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图…

电脑msvcp140丢失报错解决方法,msvcp140.dll重新安装的解决方法

msvcp140.dll丢失可能会导致一些基于Microsoft Visual C 编写的程序和游戏无法正常运行。msvcp140.dll是Microsoft Visual C Redistributable的一个组件&#xff0c;它包含了 C 运行时库&#xff0c;这些库在运行程序时会被加载到内存中。如果该文件丢失或损坏&#xff0c;程序…

MySQL SQL性能分析(SQL优化 一)

在开发和维护数据库应用程序时&#xff0c;优化SQL查询的性能是至关重要的。MySQL提供了一些强大的工具和技术&#xff0c;帮助我们进行SQL性能分析&#xff0c;找出潜在的瓶颈并进行相应的优化。 查看SQL的执行频率 show [ session| global ] status 命令查看服务器状态信息…

常见加密和解密方法介绍。

介绍常见的加密和解密方法。 加密是利用数学方法将明文转化为密文&#xff0c;从而达到保护数据的目的。 通过加密可保证数据的机密性、完整性、鉴别性。 机密性&#xff1a;通过数据加密实现。只允许特定用户访问和阅读信息。 完整性&#xff1a;通过数字加密、散列、数字签名…

结构型设计模式——外观模式

摘要 本文主要分析设计模式 - 结构型 - 外观(Facade)&#xff0c;它提供了一个统一的接口&#xff0c;用来访问子系统中的一群接口&#xff0c;从而让子系统更容易使用。 一、外观模式的意图 提供了一个统一的接口&#xff0c;用来访问子系统中的一群接口&#xff0c;从而让…

搭建前端框架

在终端进入web目录&#xff0c;然后创建vuecrud工程 创建工程并引入ElementUI和axios手把手教学>传送门:VueCLI脚手架搭建