当前位置: 首页 > news >正文

【Servlet】(Servlet API HttpServlet 处理请求 HttpServletRequest 打印请求信息 前端给后端传参)

文章目录

  • Servlet API
    • HttpServlet
      • 处理请求
    • HttpServletRequest
      • 打印请求信息
      • 前端给后端传参


Servlet API

Servlet中常用的API

HttpServlet

在这里插入图片描述
实际开发的时候主要重写 doXXX 方法, 很少会重写 init / destory / service

destory 服务器终止的时候会调用.

//下面的注解把当前类和一个HTTP请求的路径关联起来
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {@Overridepublic void init() throws ServletException {//重写init 插入自己"初始化"相关的逻辑System.out.println("init");}@Overridepublic void destroy() {System.out.println("destroy");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//这个只是在服务器的控制台打印System.out.println("hello world");//要想把hello world返回到客户端,需要使用下面的代码//getWriter 会得到一个Writer对象resp.getWriter().write("hello world");}
}

在这里插入图片描述
上面的destroy能不能被执行到有待商榷,如果是通过Smart Tomcat 的停止按钮,这个操作本质上是通过Tomcat的8005端口,主动停止,可以触发destroy.如果是直接杀进程,此时可能就来不及执行destroy就没了.因此不太推荐使用destroy.

service每次收到http请求就出触发(路径匹配)

@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.service(req, resp);}

init / destory / service 这三个方法是HttpServlet中最关键的三个方法.

Servlet的声明周期是怎么回事?

  1. 开始的时候执行init
  2. 每次收到请求执行service
  3. 销毁之前执行destroy

处理请求

@WebServlet("/method")
public class MethodServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doGet");resp.getWriter().write("doGet");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doPost");resp.getWriter().write("doPost");}@Overrideprotected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doPut");resp.getWriter().write("doPut");}@Overrideprotected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("doDelete");resp.getWriter().write("doDelete");}
}

我们刷新页面只有doGet请求,想要获得别的请求可以利用postman这个软件来实现:

在这里插入图片描述
也可以通过ajax来构造请求:先在webapp目录下创建test.html.
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><!-- 使用这个页面来构造ajax请求 --><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script><script>$.ajax({type: 'get',url: 'method',success: function(body, status){console.log(body);}});</script>
</body>
</html>

然后重启服务器,在网址栏输入:http://127.0.0.1:8080/hello_servlet/test.html然后刷新在控制台就能看到doGet请求了.想要获取别的请求,直接在代码中改就可以了,需要注意的是我们在编写Servlet代码的时候,每次修改代码,要及得重新启动服务器.
在这里插入图片描述

此处写的路径是相对路径,相对路径的基准目录是该html所在的路径.此处写method就相当于在http://127.0.0.1:8080/hello_servlet的基础上,再拼上一个method
在这里插入图片描述

绝对路径的写法:

在这里插入图片描述

HttpServletRequest

这个类表示的是HTTP请求.这个对象是Tomcat自动构造的,Tomcat会实现监听端口,接受连接,解析请求,构造请求对象等一系列工作.
下面的表格就是一些典型的方法:

方法描述
String getProtocol()返回请求协议的名称和版本
String getMethod()返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT
String getRequestURI()从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分
String getContextPath()返回指示请求上下文的请求 URI 部分
String getQueryString()返回包含在路径后的请求 URL 中的查询字符串
Enumeration getParameterNames()返回一个 String 对象的枚举,包含在该请求中包含的参数的名称
String getParameter(Stringname)以字符串形式返回请求参数的值,或者如果参数不存在则返回null
String[] getParameterValues(String name)返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null
Enumeration getHeaderNames()返回一个枚举,包含在该请求中包含的所有的头名
String getHeader(String name)以字符串形式返回指定的请求头的值
String getCharacterEncoding()返回请求主体中使用的字符编码的名称
String getContentType()返回请求主体的 MIME 类型,如果不知道类型则返回 null
int getContentLength()以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1
InputStream getInputStream()用于读取请求的 body 内容. 返回一个 InputStream 对象

打印请求信息

@WebServlet("/showRequest")
public class ShowRequestServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//设置响应的 content-type 告诉浏览器 响应的body里的格式是啥样的resp.setContentType("text/html");//搞个 StringBuilder 把这些api的结果拼起来,统一写回到响应中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>");//获取到 header 中所有的键值对Enumeration<String> headerNames = req.getHeaderNames();while (headerNames.hasMoreElements()){String headerName = headerNames.nextElement();stringBuilder.append(headerName + ": " + req.getHeader(headerName));stringBuilder.append("<br>");}resp.getWriter().write(stringBuilder.toString());}
}

在浏览器通过 URL http://127.0.0.1:8080/hello_servlet/showRequest 访问, 可以看到:
在这里插入图片描述

前端给后端传参

1.通过GET里的query string

在前端给后端传两个数字,一个是同学的studentId,一个是classId

@WebServlet("/getParameter")
public class GetParameterServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//预期浏览器会发一个形如 /getParameter?studentId=10&classId=20 这样的请求// 借助req 里的 getParameter方法就能拿到 query string 中的键值对内容//getParameter 得到的是 String 类型的结果String studentId = req.getParameter("studentId");String classId = req.getParameter("classId");resp.setContentType("text/html");resp.getWriter().write("studentId = " + studentId + " classId = " + classId);}
}

在这里插入图片描述
如果key在query string中不存在,此时就返回值就是null

2.通过POST,借助form表单的方式
对于前端是form表单这样格式的数据(也是键值对,和query string的格式一样,只是这部分内容在body中),后端还是使用getParameter来获取.

前端代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><form action="postParameter" method="post"><input type="text" name="studentId"><input type="text" name="classId"><input type="submit" value="提交"></form>
</body>
</html>

在这里插入图片描述

后端代码:

@WebServlet("/postParameter")
public class PostParameterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String studentId = req.getParameter("studentId");String classId = req.getParameter("classId");resp.setContentType("text/html");resp.getWriter().write("studentId = " + studentId + " classId = " + classId);}
}

在这里插入图片描述

使用getParameter 既可以获取到query string 中的键值对,也可以获取到form表单构造的body中的键值对.

在这里插入图片描述

3.POST里的json

json是一种非常主流的数据格式,也是键值对结构.
在这里插入图片描述
我们可以把body按照这个格式来组织.前端可以通过ajax的方式来构造出这个内容,更简单的方法使用postman直接构造.

在这里插入图片描述

后端代码:

@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//通过这个方法来处理 body 为 json 格式的数据//直接把 req 对象里 body 完整的读取出来//getInputStream// 在流对象中读多少字节取决于Content-Lengthint length = req.getContentLength();byte[] buffer = new byte[length];InputStream inputStream = req.getInputStream();inputStream.read(buffer);//把这个字节数组构造成 String 打印出来String body = new String(buffer,0,length,"utf8");System.out.println("body =" + body);resp.getWriter().write(body);}
}

然后在postman那块点击Send请求,服务器也相对应打印出了从body中读出的数据.
在这里插入图片描述

总结:借助postman构造出post请求,body就是json数据,请求到达Tomcat,Tomcat解析成req对象,再通过req.getInputStream读取body内容,把读出的结果构造成响应往回写,最后postman客户端收到了对应的结果.

当前通过json传递数据,但是服务器这边只是把整个body读出来,没有按照键值对的方式来处理,还不能根据key获取value,为了解决这个问题,我们可以使用jackson第三方库.

通过maven引入第三方库:

在这里插入图片描述

在这里插入图片描述

将所选的内容粘贴到pom.xml当中:

在这里插入图片描述

然后上面的后端代码就需要改变:

class Student{public int studentId;public int classId;
}
@WebServlet("/postParameter2")
public class PostParameter2Servlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Student student = objectMapper.readValue(req.getInputStream(),Student.class);System.out.println(student.studentId + ", " + student.classId);}
}

在这里插入图片描述

相关文章:

【Servlet】(Servlet API HttpServlet 处理请求 HttpServletRequest 打印请求信息 前端给后端传参)

文章目录 Servlet APIHttpServlet处理请求 HttpServletRequest打印请求信息前端给后端传参 Servlet API Servlet中常用的API HttpServlet 实际开发的时候主要重写 doXXX 方法, 很少会重写 init / destory / service destory 服务器终止的时候会调用. //下面的注解把当前类和…...

java中右移>>和无符号右移>>>的区别

public static void main(String[] args) {byte[] dest new byte[2];dest[0] 0x15; //0001 0101dest[1] (byte) 0xfb;//1111 1011System.out.println((dest[0] >> 4) & 0xff);//右移 应该是0000 0001 十进制结果显示1 结果也是1&#xff0c;正确System.out.printl…...

牛客周赛 Round 7

目录 A 游游的you矩阵 题目&#xff1a; 题解&#xff1a; AC 代码&#xff1a; B 游游的01串操作 题目&#xff1a; 题解&#xff1a; AC 代码&#xff1a; C 游游的正整数 题目&#xff1a; 题解&#xff1a; AC 代码&#xff1a; D 游游的选数乘积 题目&#xf…...

R语言生存分析(机器学习)(1)——GBM(梯度提升机)

GBM是一种集成学习算法&#xff0c;它结合了多个弱学习器&#xff08;通常是决策树&#xff09;来构建一个强大的预测模型。GBM使用“Boosting”的技术来训练弱学习器&#xff0c;这种技术是一个迭代的过程&#xff0c;每一轮都会关注之前轮次中预测效果较差的样本&#xff0c;…...

k8s和docker简单介绍

当涉及到容器技术和容器编排时&#xff0c;Docker和Kubernetes是两个重要的概念。我将更详细地介绍它们以及它们之间的关系。 Docker&#xff1a; Docker是一种容器化技术&#xff0c;它允许你将应用程序及其依赖项打包到一个称为"容器"的封闭环境中。每个容器都包…...

Lua学习记录

Lua基础了解 Lua的注释通过 (-- 单行注释&#xff0c;--[[ ]] 多行注释)可以不加&#xff1b; 多个变量赋值&#xff0c;按顺序赋值&#xff0c;没有则为nil&#xff1b; function的简单用法&#xff0c;多个返回值配合多重赋值&#xff0c;以end为结束标志 Lua下标从1开始&…...

三分钟完美解决你的C盘内存过大爆红

一、清理回收站 二、清理桌面 建议一 不要在桌面放太多图标或者文件会占用过多的内存,可以放到其他盘建议二、 将位置移动到别的盘 三、手动删除下载文件与缓存文件 日常使用中会通过Windows下载各种文件资料到电脑中&#xff0c;它默认也是直接下载在C盘中的。如果我们在以…...

C++ - equal(比较两个vector元素)

C标准库的std::equal函数。这个函数用于比较两个范围的元素是否相等。 在使用std::equal函数时&#xff0c;您需要提供两个范围的迭代器&#xff0c;以及一个可选的谓词函数&#xff08;predicate&#xff09;。函数会比较第一个范围内的元素和第二个范围内的元素是否相等。如果…...

多线程:线程池

线程池 提前创建多个线程放入线程池中&#xff0c;使用时直接获取&#xff0c;使用完直接放入池中&#xff1b;可以避免频繁创建销毁&#xff0c;实现重复利用&#xff0c;类似生活中的公共交通工具。好处&#xff1a;提高相应速度&#xff1b;降低资源消耗&#xff1b;便于线…...

9.3.2.2网络原理(传输层TCP)

TCP全部细节参考RFC标准文档 一.TCP特点: 有连接,可靠传输,面向字节流,全双工. 二.TCP数据报: 1.端口号是传输层的重要概念. 2.TCP的报头是变长的(UDP是固定的8字节),大小存在4位首部长度中,用4个bit位(0~15)表示长度单位是4字节.(TCP报头最大长度是60字节,前面20字节是固定…...

ssm+mybatis无法给带有下划线属性赋值问题

原因&#xff1a;mybaitis根据配置&#xff0c;将有下划线的字段名改为了驼峰格式。 具体见&#xff1a;ssmmybatis无法给带有下划线属性赋值问题&#xff0c;无法获取数据库带下划线的字段值 - 开发者博客 解决方式&#xff1a; 直接将实体类中的下划线去掉返回值使用resul…...

学习笔记-JVM监控平台搭建

SpringBoot Actuator 1 引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId> </dependency>2 开启配置 # 暴露所有的监控点【含Prometheus】 management.endpoin…...

使用css实现时间线布局(TimeLine)

前言 在使用uni-app开发微信小程序过程中&#xff0c;遇到了时间轴布局&#xff0c;由于每项的内容高度不一致&#xff0c;使用uniapp自带的扩展组件uni-steps&#xff0c;样式布局无法对齐竖线&#xff0c;于是自己造轮子&#xff0c;完成特殊的布局。显示效果如下&#xff1…...

深入浅出 栈和队列(附加循环队列、双端队列)

栈和队列 一、栈 概念与特性二、Stack 集合类及模拟实现1、Java集合中的 Stack2、Stack 模拟实现 三、栈、虚拟机栈、栈帧有什么区别&#xff1f;四、队列 概念与特性五、Queue集合类及模拟实现1、Queue的底层结构&#xff08;1&#xff09;顺序结构&#xff08;2&#xff09;链…...

前端基础(二)

前言&#xff1a;前端开发框架——Vue框架学习。 准备工作&#xff1a;添加Vue devtools扩展工具 具体可查看下面的这篇博客 添加vue devtools扩展工具添加后F12不显示Vue图标_MRJJ_9的博客-CSDN博客 Vue官方学习文档 Vue.js - 渐进式 JavaScript 框架 | Vue.js MVVM M…...

ORB-SLAM2学习笔记7之System主类和多线程

文章目录 0 引言1 整体框架1.1 整体流程 2 System主类2.1 成员函数2.2 成员变量 3 多线程3.1 ORB-SLAM2中的多线程3.2 加锁 0 引言 ORB-SLAM2是一种基于特征的视觉SLAM&#xff08;Simultaneous Localization and Mapping&#xff09;系统&#xff0c;它能够从单个、双目或RBG…...

gin的占位符:和通配符*

1、用法 在 Gin 路由中&#xff0c;可以使用一个通配符&#xff08;*&#xff09;或一个占位符&#xff08;:&#xff09;来捕获 URL 的一部分。 r.GET("/royal/:id", func(c *gin.Context) {id : c.Param("id")//fmt.Println("into :id")c.Str…...

【量化课程】08_2.深度学习量化策略基础实战

文章目录 1. 深度学习简介2. 常用深度学习模型架构2.1 LSTM 介绍2.2 LSTM在股票预测中的应用 3. 模块分类3.1 卷积层3.2 池化层3.3 全连接层3.4 Dropout层 4. 深度学习模型构建5. 策略实现 1. 深度学习简介 深度学习是模拟人脑进行分析学习的神经网络。 2. 常用深度学习模型架…...

12-数据结构-数组、矩阵、广义表

数组、矩阵、广义表 目录 数组、矩阵、广义表 一、数组 二.矩阵 三、广义表 一、数组 这一章节理解基本概念即可。数组要看清其实下标是多少&#xff0c;并且二维数组&#xff0c;存取数据&#xff0c;要先看清楚是按照行存还是按列存&#xff0c;按行则是正常一行一行的去读…...

Idea 反编译jar包

实际项目中&#xff0c;有时候会需要更改jar包源码来达到业务需求&#xff0c;本文章将介绍一下如何通过Idea来进行jar反编译 1、Idea安装decompiler插件 2、找到decompiler插件文件夹 decompiler插件文件夹路径为&#xff1a;idea安装路径/plugins/java-decompiler/lib 3、…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)

Name&#xff1a;3ddown Serial&#xff1a;FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名&#xff1a;Axure 序列号&#xff1a;8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...