【Servlet】——Servlet API 详解

个人主页:兜里有颗棉花糖
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创
收录于专栏【Servlet】
本专栏旨在分享学习Servlet的一点学习心得,欢迎大家在评论区交流讨论💌

目录

  • 一、HttpServlet
  • 二、HttpServletRequest
    • 核心方法
    • 代码示例1
    • 如何获取query string和body(form格式)中的数据
    • 获取body(json格式)中的数据
      • jackon依赖的导入
  • 三、HttpServletResponse
    • setStatus
    • setHeader
    • 构造重定向响应
    • 返回一个html界面

API就是一组类和方法,本文中我们学习Servlet API的三个类:HttpServletHttpServletRequestHttpServletResponse

一、HttpServlet

HttpServlet是我们编写Servlet代码用来的核心类,通过继承这个类并重写其中的方法,然后Tomcat去调用其中的代码逻辑。可以这样理解:我们这里写的代码(重写的方法)并不是我们自己手动调用手动执行的,而是将我们写地代码交给Tomcat,让Tomcat帮助我们执行调用这些代码。

核心方法如下:

在这里插入图片描述

  • Init方法:在webapp被加载的时候会调用此方法,可以使用该方法进行初始化操作。
  • destroy方法:在webapp被销毁(或Tomcat结束)的时候执行destroy方法,可以使用该方法进行收尾工作。注意:该方法不能保证一定会被调用到。

这里分为两种情况。

第一种情况:通过8005端口给Tomcat发起一个特殊的请求,然后Tomcat就关闭了(这种情况可以调用到destroy方法)。
第二种情况:直接杀死Tomcat进程,比如说通过任务资源管理器直接结束Tomcat任务进程,此时就无法执行destroy方法。

实际开发中第二种情况占多数(尤其是在Linux中),这就提醒我们不能依赖destroy方法,因为该方法不一定被调用到。

  • service方法:每次收到请求会执行service方法,处理每个请求。一般会使用doXXX方法来替代service方法

对于上述方法,浏览器只能构造Get方法,对于其它的方法浏览器并不方便构造。如果想要构造其它的请求方法,我们可以使用ajax或者postman。

在这里插入图片描述
实际开发中用到的最多的是Get和Post。

二、HttpServletRequest

HttpServletRequestJava Servlet API提供的接口之一,用于表示客户端的HTTP请求。

一个HTTP请求中都有哪些信息都会在HttpServletRequest类中进行体现。当Tomcat接收到Http请求时,它将解析请求并将相关的信息填充到HttpServletRequest对象中,从而使开发人员可以方便地获取和处理这些信息。

核心方法

下图是HttpServletRequest的方法:
在这里插入图片描述

  • URI和URL:URI是唯一资源标识符,URL是唯一资源定位符;URI用来区分不同的资源,而URL就是用来区分不同资源的一种方式。我们可以这样理解,URL是URI的实现方式。实际开发中一般会混着用。

Enumeration getParameterNames()String getParameter(String name)
我们直到请求中可以通过一些方式把自定义数据传递到服务器中,有两种方式:
第一种方式:query stringquery string是键值对结构的数据,Tomcat收到请求后就会把query string解析成Map这样的键值对。然后使用getParameter就可以根据key获取到value;而getParameterNames是拿到所有的key。
第二种方式:body:如果是通过post form表单的形式提交表单的话,此时body中也是键值对的形式(和query string一样)。

getParameterValues方法:即一个key涉及到多个value。

Enumeration getHeaderNames()String getHeader(String name):获取到请求头中的键值对,Tomcat收到请求后也会把请求头解析成Map。getHeader是通过key拿到指定的value;而getHeaderNames是拿到所有的key。

代码示例1

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;@WebServlet("/request")
public class RequestServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 下行代码就是为了显示告诉浏览器,浏览器拿到的内容是htmlresp.setContentType("text/html");// 调用req的各个方法,把得到的结果汇总到一个字符串中,然后统一返回到桌面上StringBuilder respBody = new StringBuilder();// 由于下面的内容在浏览器是按照html展示的,\n在浏览器上并不是换行,所以使用<br>来表示换行// 获得HTTP请求协议的版本号respBody.append(req.getProtocol());respBody.append("<br");// 获取HTTP请求方法respBody.append(req.getMethod());respBody.append("<br>");// 获取请求的URIrespBody.append(req.getRequestURI());respBody.append("<br>");// 将req.getContextPath()返回的上下文路径添加到respBody中respBody.append(req.getContextPath());respBody.append("<br>");// 返回的查询字符串添加到respBody字符串中的代码respBody.append(req.getQueryString());respBody.append("<br>");// 拼接headerEnumeration<String> headers = req.getHeaderNames();while(headers.hasMoreElements()) {String header = headers.nextElement();respBody.append("<br>");respBody.append(header + ": " + req.getHeader(header));}resp.getWriter().write(respBody.toString());}
}

跑起来之后如下图:
在这里插入图片描述

如何获取query string和body(form格式)中的数据

如何获取query string中的数据

代码如下:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/parameter")
public class ParameterServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String password = req.getParameter("password");System.out.println("username=" + username);System.out.println("password=" + password);resp.getWriter().write("OK");}
}

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

如何获取中body的数据

由于body有很多种格式,所以这里就拿form表单格式(和query string格式一样是键值对的格式)来举例。这里我们让客户端发送一个Post请求,同时使用form格式的数据在body中把数据进行传递。

代码如下:

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@WebServlet("/parameter2")
public class Parameter2Servlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String password = req.getParameter("password");System.out.println("username=" + username);System.out.println("password=" + password);resp.getWriter().write("OK");}
}

结果如下:
在这里插入图片描述

在这里插入图片描述

总结:使用getParameter()方法可以用于获取query string中的value值以及form表单中的value值。
所以我们完全可以使用一种代码来获取query string中的value值以及form表单中的value值(doPost()方法用于处理POST请求,获取表单中的参数值。doGet()方法用于处理GET请求,获取查询字符串中的参数值)。
注意:上述两份代码的servlet path是不能重复的,否则会出现404报错。

获取body(json格式)中的数据

再来回顾一下json格式:

{username:lisi;password:9521;
}

json格式虽然在开发中也是经常会用到的一种格式,但是Servlet自身不能够对json格式的数据进行解析。解决方式是引入第三方库来进行解析(将键值对还原成Map这种key value的形式)。

解析json格式的第三方库也是有很多的,我们这里使用jackon来对json进行解析。

jackon依赖的导入

在这里插入图片描述
然后这里选择一个版本(建议选旧版本)
在这里插入图片描述
然后复制粘贴到pom.xml文件中去。
在这里插入图片描述
注意是复制粘贴到<dependencies></dependencies>标签中(一个dependencies标签可以包含多个依赖)。
在这里插入图片描述
最后刷新一下即可。

jackon依赖引入的是一个类两个方法:类是ObjectMapper,用于将Java对象转换为JSON格式的字符串,也可以将JSON字符串转换回相应的Java对象。

现在我们回归正题:获取body(json格式)中的数据(即客户端中的body按照json格式进行传输)。

在这里插入图片描述
readValue方法选择上图中的版本。该方法的作用就是把json格式的字符串解析成Java对象。
第一个参数(InputStream src)可以看到是一个流对象,表示json从哪里来。
第二个参数(JavaType valueType)用于指定一个类型:即json格式的字符串需要解析成什么类型的Java对象(这是一个将json格式的字符串映射成java对象的过程)。
关于第二个参数:我们需要定义一个类,该类的属性名称与 JSON 字符串中的字段匹配(如下图)
在这里插入图片描述
完成代码如下:

import com.fasterxml.jackson.databind.ObjectMapper;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;//{
//    "username":"lisi",
//    "password":"465"
//}class User {public String username;public String password;
}@WebServlet("/json")
public class JsonServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {ObjectMapper objectMapper = new ObjectMapper();User user = objectMapper.readValue(req.getInputStream(),User.class);System.out.println("username=" + user.username + ", password=" + user.password);resp.getWriter().write("OK");}
}

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

在这里插入图片描述

总结:readValue方法将req请求中的body(json格式)中的字符串读取并解析,然后构造成了user对象,而user中的属性就是body(json格式)中所体现的内容。

jackon还提供了一个方法可以将java对象转换成json格式的字符串。该方法为writeValueAsString()
在这里插入图片描述

三、HttpServletResponse

HttpServletResponse是用于构造HTTP响应的对象,提供了一系列方法用于操作响应的状态码、头部信息(header)和响应体数据(body)。它和HTTP响应数据相匹配,可以用于向客户端发送响应数据。然后针对状态码、header、body这些属性就可以进行设置。

注意区分下面两个概念:
请求对象:拿到请求对象之后是为了获取对象中的属性(读操作)。
响应对象:拿到响应对象之后是为了设置对象中的属性(写操作)。

而对于doXXX这样的方法的作用就是根据请求计算响应。
再强调一下:请求对象是Tomcat收到后对Http协议解析得到的对象。
而响应对象是Tomcat创建空的对象,然后在代码中把响应对象的属性设置好。

下面来看HttpServletResponse中的核心方法,如下:
在这里插入图片描述

  • addHeader():可能会出现key相同的两个键值对(一个key可以对应多个value)。另外,Java标准库的Map是不允许key重复的,Tomcat内部也不一定把header解析成Map。
  • setHeader():一个key对应一个value。
  • setCharacterEncoding:告诉浏览器按照什么样的字符集来解析响应的body。
  • sendRedirect:用来设定重定向响应。

setStatus

代码示例1如下:
在这里插入图片描述
运行结果如下:
在这里插入图片描述

代码示例2如下:
在这里插入图片描述
运行结果如下:
在这里插入图片描述

在返回状态码的同时,可以给body写入数据,这样就可以得到比较个性化的错误页面,比如:
在这里插入图片描述
上图就是搜狗的404错误页面。
在这里插入图片描述
上图就是百度的404错误页面。
在这里插入图片描述
上图是哔哩哔哩的404错误页面。

Tomcat同样有一个内置的404报错页面,虽然setStatus方法并没有页面,但是sendError方法是有页面的。代码如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上图是Tomcat的404报错页面。

setHeader

我们通过使用setHeader方法来设置任意的响应报头。举例:通过refresh属性来设置浏览器自动刷新(比如refresh:2,意思就是浏览器每隔两秒就会自动刷新)。

代码如下:
在这里插入图片描述

运行结果如下(下图中的时间每隔两秒就会改变):在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

构造重定向响应

让页面重定向到百度主页。

注意:使用重定向一定要带有Location属性,然后用这个属性来描述你要重定向到哪个地方

代码如下:
在这里插入图片描述

结果如下:
在这里插入图片描述

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

补充:
301:永久重定向
302:临时重定向

刚刚上述代码可以等价替换成下面代码:
在这里插入图片描述在这里插入图片描述

resp.sendRedirect("https://www.baidu.com");等价于resp.setStatus(302);resp.setHeader("Location","https://www.baidu.com");(浏览器看到302和https://www.baidu.com这两个字段就知道要跳转到百度)

返回一个html界面

在这里插入图片描述
结果如下:
在这里插入图片描述
为什么会出现乱码呢?

我们要知道,如果在IDEA中直接写一个中文字符串的话是按照utf-8进行编码的。但是浏览器默认是使用操作系统的编码方式来解析和显示页面,而windows简体中文版的默认编码方式是gdk,此时浏览器按照gdk的方式来解析utf-8的话就会出现上图中的乱码。

所以我们要设置一下让浏览器按照utf-8的方式进行解析(如下)。
在这里插入图片描述
在这里插入图片描述

上述代码还存在一个问题,如下(将doGet方法中的两行代码进行互换):
在这里插入图片描述
在这里插入图片描述
可以看到又出现了乱码。在Servlet中,为resp设置属性的时候,需要注意顺序:要先设置header,然后再设置body;否则如果先设置body的话此时header、status就已经定性而来不及修改了

好了,以上就是本文的全部内容了。希望各位友友可以一键三连哈!!!

在这里插入图片描述

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

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

相关文章

spring boot yaml文件中如何设置duration对象值

Spring Boot对表示持续时间有专门的支持。如果您公开java.time.Duration属性&#xff0c;则应用程序对应Duration类型的属性有以下格式可用: long类型的常规表示(使用毫秒作为默认单位&#xff0c;除非指定了DurationUnit)java.time.Duration 使用的标准ISO-8601格式其中值和单…

鸿蒙ArkUI日期选择组件

鸿蒙ArkUI日期选择组件&#xff0c;基于基础组件进行的二次封装的日期选择组件&#xff0c;快速实现日期选择。 /*** 日期*/ Component export default struct DiygwDate{//绑定的值Link Watch(onValue) value:string;// 隐藏值State valueField: string value;// 显示值Sta…

6+单基因+单细胞+实验,干湿结合是生信分析发文最真诚的必杀技

今天给同学们分享一篇生信文章“CXCR4 expression is associated with proneural-to-mesenchymal transition in glioblastoma”&#xff0c;这篇文章发表在Int J Cancer期刊上&#xff0c;影响因子为6.4。 结果解读&#xff1a; CXCR4表达与PN GBM的存活和MES标记物的表达相关…

Echarts+Vue 首页大屏静态示例Demo 第三版

效果图: 源码: <template><div class="content bg" style="height: 100vh;overflow-y: auto" :class="{ fullscreen-container: isFullScreen }"><div class="reaDiv" style="height: 10vh"><div…

MySQL 5.7.36安装操作

接上文提示&#xff1a; 【Config Type】选项用于设置服务器的类型。单击该选项右侧的下三角按钮&#xff0c;即可看到 3个选项&#xff0c;如图10所示。 Development Machine&#xff08;开发者机器&#xff09;&#xff1a;代表典型的个人桌面工作站。假定机器上运行着多个…

4.java中的输入输出/输入中的next和nextLine区别问题

&#xff08;笔试会经常让我们自己去处理输入输出&#xff09; 一.输出到控制台 println 输出的内容自带 \n&#xff08;换行&#xff09; print 不带 \n printf 的格式化输出方式和 C 语言的 printf 是基本一致的. String msg "Hello, World!";System.out.print(m…

Transformer 自然语言处理(四)

原文&#xff1a;Natural Language Processing with Transformers 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第十章&#xff1a;从头开始训练变换器 在本书的开头段落中&#xff0c;我们提到了一个名为 GitHub Copilot 的复杂应用&#xff0c;它使用类似 GPT 的…

前缀和 差分

差分和前缀和都是算法里边比较重要的知识点&#xff0c;不过学习的难度并不高&#xff0c;这篇文章会讲解相关的内容。 1. 前缀和怎么玩 1&#xff09;一维前缀和 在该数之前&#xff0c;包括该数的所有数之和&#xff0c;有点类似高中学的数列的前n项和Sn。 2&#xff09;二维…

Spring框架——主流框架

文章目录 Spring(轻量级容器框架)Spring 学习的核心内容-一图胜千言IOC 控制反转 的开发模式Spring快速入门Spring容器剖析手动开发- 简单的 Spring 基于 XML 配置的程序课堂练习 Spring 管理 Bean-IOCSpring 配置/管理 bean 介绍Bean 管理包括两方面: Bean 配置方式基于 xml 文…

Unity DOTween插件常用方法(二)

文章目录 1.3 动画设置1.4 动画队列 Sequence1.5 动画回调函数1.6 等待函数&#xff08;协程中使用&#xff09; 1.3 动画设置 SetLoops 设置循环动画&#xff1b; 参数&#xff1a; loops&#xff1a;指定循环的次数&#xff0c;设置为 -1 表示无限循环&#xff1b; loopType…

洛谷p1644跳马问题

跳马问题 题目背景 在爱与愁的故事第一弹第三章出来前先练练四道基本的回溯/搜索题吧…… 题目描述 中国象棋半张棋盘如图 1 1 1 所示。马自左下角 ( 0 , 0 ) (0,0) (0,0) 向右上角 ( m , n ) (m,n) (m,n) 跳。规定只能往右跳&#xff0c;不准往左跳。比如图 1 1 1 中所…

Windows篇|连接共享文件夹映射驱动器教程

前言 昨天给小伙伴们分享了如何设置Windows共享文件夹的教程 超简单设置Windows共享文件夹,传输文件无烦恼 A电脑设置完共享文件夹之后,只要在同一局域网下,所有的电子设备都可以连接访问A电脑的共享文件夹里的内容。 这样就省去了U盘传输的麻烦,只要A电脑开着机,文件放入…

基于SpringBoot+Vue的校园资料分享平台(V2.0)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【GitHub项目推荐--ChatGPT开源项目】【转载】

Auto-GPT Auto-GPT 是一个实验性的开源项目&#xff0c;基于 GPT-4。你给出 Auto-GPT 一个的任务&#xff0c;它不会立即输出答案&#xff0c;而会先自己通过多轮对话来琢磨、验证、决策&#xff0c;从而自己找出一条达成目标的路&#xff0c;整个过程完全不需要人类插手&…

【C++游戏开发-01】推箱子

C游戏开发 文章目录 C游戏开发[TOC](文章目录) 前言一、逻辑分析1.1地图实现1.2人物的移动1.2.1小人移动1.2.2其他移动 1.3墙壁的碰撞1.4箱子的推动1.4.1什么时候推箱子1.4.2什么情况可以推箱子 1.5胜利的判断1.6卡关的处理1.7关卡的切换 二、DEMO代码2.1游戏框架2.2各功能函数…

Python实战:使用DrissionPage库爬取高考网大学信息

上一篇文章&#xff0c;我刚入门 DrissionPage 爬虫库&#xff0c;使用这个库爬取了拉钩网关于 Python 的职位信息。 今天再使用 DrissionPage 爬虫库练习一个案例&#xff0c;爬取高考网大学信息。 本次爬取到2885个大学信息&#xff0c;包含大学名称、所在省、市、大学标签信…

Galah:一款功能强大的LLM驱动型OpenAI Web蜜罐系统

关于Galah Galah是一款功能强大的Web蜜罐&#xff0c;该工具由LLM大语言模型驱动&#xff0c;基于OpenAI API实现其功能。 很多传统的蜜罐系统会模拟一种包含了大量网络应用程序的网络系统&#xff0c;但这种方法非常繁琐&#xff0c;而且有其固有的局限性。Galah则不同&…

【算法详解 | 二分查找】详解二分查找 \ 折半查找高效搜索算法 | 顺序数组最快搜索算法 | 递归循环解决二分查找问题

二分查找 by.Qin3Yu 本文需要读者掌握 顺序表 的操作基础&#xff0c;完整代码将在文章末尾展示。 顺序表相关操作可以参考我的往期博文&#xff1a; 【C数据结构 | 顺序表速通】使用顺序表完成简单的成绩管理系统.by.Qin3Yu 文中所有代码使用 C 举例&#xff0c;且默认已使用…

聊一聊Tomcat的架构和运行流程,尽量通俗易懂一点

1、Tomcat的架构 这里可以看出 A、一个Tomcat就是一个Server&#xff0c;一个Server下会有多个Service&#xff0c; B、Service只负责封装多个Connector和一个Container&#xff08;Service本身不是容器&#xff0c;可以看做只是用来包装Connector和Container的壳&#xff0c…

基于Springboot的社区疫情防控平台

末尾获取源码作者介绍&#xff1a;大家好&#xff0c;我是墨韵&#xff0c;本人4年开发经验&#xff0c;专注定制项目开发 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 一、项目简介 以往的社区疫情防控管理…