ServletAPI详解(三)-HttpServletRequest

news2024/11/17 14:35:29

我们来看第二个类:HttpServletRequest

HttpServletRequest

HttpServletRequest表示的是一个http请求对象,是tomcat自动构造的,tomcat会实现监听端口,接收连接,读取请求,解析请求,构造请求对象等一系列操作

下面的方法可用在 Servlet 程序中读取 HTTP 头。这些方法通过 HttpServletRequest 对象可用。

序号方法 & 描述
1Cookie[] getCookies()
返回一个数组,包含客户端发送该请求的所有的 Cookie 对象。
2Enumeration getAttributeNames()
返回一个枚举,包含提供给该请求可用的属性名称。
3Enumeration getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
4Enumeration getParameterNames()
返回一个 String 对象的枚举,包含在该请求中包含的参数的名称。
5HttpSession getSession()
返回与该请求关联的当前 session 会话,或者如果请求没有 session 会话,则创建一个。
6HttpSession getSession(boolean create)
返回与该请求关联的当前 HttpSession,或者如果没有当前会话,且创建是真的,则返回一个新的 session 会话。
7Locale getLocale()
基于 Accept-Language 头,返回客户端接受内容的首选的区域设置。
8Object getAttribute(String name)
以对象形式返回已命名属性的值,如果没有给定名称的属性存在,则返回 null。
9

ServletInputStream getInputStream()
使用 ServletInputStream,以二进制数据形式检索请求的主体。

用于读取请求的body内容,返回一个InputStream对象

10String getAuthType()
返回用于保护 Servlet 的身份验证方案的名称,例如,"BASIC" 或 "SSL",如果JSP没有受到保护则返回 null。
11String getCharacterEncoding()
返回请求主体中使用的字符编码的名称。
12String getContentType()
返回请求主体的 MIME 类型,如果不知道类型则返回 null。
13String getContextPath()
返回指示请求上下文的请求 URI 部分。
14String getHeader(String name)
以字符串形式返回指定的请求头的值。
15String getMethod()
返回请求的 HTTP 方法的名称,例如,GET、POST 或 PUT。
16

String getParameter(String name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。

querystring是查询字符串,是键值对的结构,这个方法通过key来获取到value

17String getPathInfo()
当请求发出时,返回与客户端发送的 URL 相关的任何额外的路径信息。
18String getProtocol()
返回请求协议的名称和版本。
19String getQueryString()
返回包含在路径后的请求 URL 中的查询字符串。
20String getRemoteAddr()
返回发送请求的客户端的互联网协议(IP)地址。
21String getRemoteHost()
返回发送请求的客户端的完全限定名称。
22String getRemoteUser()
如果用户已通过身份验证,则返回发出请求的登录用户,或者如果用户未通过身份验证,则返回 null。
23String getRequestURI()
从协议名称直到 HTTP 请求的第一行的查询字符串中,返回该请求的 URL 的一部分。
24String getRequestedSessionId()
返回由客户端指定的 session 会话 ID。
25String getServletPath()
返回调用 JSP 的请求的 URL 的一部分。
26String[] getParameterValues(String name)
返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null。
27boolean isSecure()
返回一个布尔值,指示请求是否使用安全通道,如 HTTPS。
28int getContentLength()
以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1。
29int getIntHeader(String name)
返回指定的请求头的值为一个 int 值。
30int getServerPort()
返回接收到这个请求的端口号。
31int getParameterMap()
将参数封装成 Map 类型。

 通过代码演示主要的方法

创建一个StringBuilder,将api的结果拼接起来写回到响应中

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("/showRequest")
public class ShowRequestServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建一个StringBuilder,将api的结果拼接起来写回到响应中
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(" ");
        //协议名称
        stringBuilder.append(req.getProtocol());
        stringBuilder.append(" ");
        //方法名称
        stringBuilder.append(req.getMethod());
        stringBuilder.append(" ");
        //URL
        stringBuilder.append(req.getRequestURL());
        stringBuilder.append(" ");
        //项目路径
        stringBuilder.append(req.getContextPath());
        stringBuilder.append(" ");
        //查询字符串
        stringBuilder.append(req.getQueryString());

        //写回
        resp.getWriter().write(stringBuilder.toString());
    }
}

启动服务器,发现有个错误

 Caused by: java.lang.IllegalArgumentException: servlet映射中的<url pattern>[showRequest]无效

这个是因为注解不正确,一定不要忘记/

@WebServlet("/showRequest")

我们看结果

833406da18d94a2f986a16e05be0f25f.png

获取header中的所有键值对
Enumeration getHeaderNames()
返回一个枚举,包含在该请求中包含的所有的头名。
resp.setContentType("text/html");设置内容类型后,浏览器会按照这个解析

4abd8ec7f98c44109d8d4a9133eb0a87.png

5888eb26d9e34581977ac59453670686.png

发送请求后如果进行抓包,看到的结果也是相同的


接下来我们说说前端如何给后端传参

方式:

1.GET,querystring

获取 GET 请求中的参数

GET 请求中的参数一般都是通过 query string 传递给服务器的

String getParameter(String name)
以字符串形式返回请求参数的值,或者如果参数不存在则返回 null。

querystring是查询字符串,是键值对的结构,这个方法通过key来获取到value

前端给后端传输两个数字,studentId, classId

?studentId=1&classId=30

@WebServlet("/getParameter")

public class GetParameterServlet extends HttpServlet {
    //预期浏览器会发送一个/getParameter?studentId=1&classId=30请求
    //借助req的getParameter方法获取到querystring的键值对内容

    @Override
    protected void doGet(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);
    }
}

获取到了 ,可以看到query string键值对会被tomcat处理成Map的结构,就可以用getParameter方法通过key获取到值了,如果key不存在,就返回null

2b3fa833d8504a329e979d47b21bd19c.png

2.POST,form

POST 请求的参数一般通过 body 传递给服务器

body 中的数据格式有很多种. 如果是采用 form 表单的 形式, 仍然可以通过 getParameter 获取参数的值.

服务器代码几乎不变,还是使用getParameter方法获取

form之前也讲到过,和querystring的格式是一样的,只是内容在body中

我们现在通过HTML的form标签构造请求

    <!-- form表单构造请求 -->
    <form action="postParameter" method="post">
        <input type="text" name="studentId">
        <input type="text" name="classId">
        <input type="submit" value="提交">
    </form>

 重启服务器

4abdaeaf423a48869741e1f058f2b207.png

抓包结果与代码的对比

5b092fd944c14074984fa71493dfa507.png

Content-Type: application/x-www-form-urlencoded

说明了是通过form表单构造的请求

后端还未构造,所以发送请求后404了

e57841a413c64d77970b5bf68ee64d9d.png 构造后端代码

@WebServlet("/postParameter")
public class PostParameterServlet extends HttpServlet {
    @Override
    protected 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);
    }
}

代码和GET,querystring后端代码相同,但是这里构造的请求内容是在body中

4af2fe4e14194fce868e365a6316bb51.png

整个前后端交互过程: 

73c6c07e2ea54392b821d8fa9c7e19b3.png

使用getParameter方法既可以获取querystring中的键值对,也可以获取到form表单构造的body中的键值对

3.POST,josn

 josn也是一种常用的数据格式,也是键值对结构

如果 POST 请求中的 body 是按照 josn的格式来传递, 那么获取参数的代码就要发生调整

前端可以通过ajax方式构造,或者使用postman构造

4c7b1a22115f4824a4e81cbc1b47c1ec.png

后端代码

@WebServlet("/postParameter2")
public class GetParameter2Servlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //通过这个方法来处理body为json格式的数据
        //将req对象里的body完整读取
        //getInputStream
        //在流对象中读取字节多少取决于Content-Lengt
        int length = req.getContentLength();
        byte[] buffer = new byte[length];

        InputStream inputStream = req.getInputStream();
        inputStream.read(buffer);

        //构造成String
        String body  = new String(buffer);
        System.out.println("body = "+ body);
        resp.getWriter().write(body);
    }
}

启动服务器后,点击postman的send发送请求

服务器打印出了

读到的body,是从请求的body中获取到的 

ce08f6b3d4e14d7996e7a27673591c1e.png

抓包也能看到

0223bc614b944e938b5f47bbba1ef171.png

 交互过程:

postman构造请求,请求到达tomcat后被解析成req对象

后端代码req.getInputStream();读取body内容并构造成resp对象返回给postman

b1eafb9520d24b8cbb280d4c969324dd.png

 当前通过传递数据,服务器只能将body整个读出来,不能通过键值对的形式管理,也不能通过key获取到value

可以使用第三方库解析,比如jackson,spring mvc天然内置了jackson这个库来解析json格式

通过maven引入第三方库

4758e4c60ed74950832c4d783d9db126.png

9bdb8c7d4e5e424a9017c68697882d06.png 粘贴到pom.xml文件的依赖中,0e821a43828b48ed92dc0f0cd557a082.png

如果红了就刷新,导入依赖项

更改代码

14f3cb666bdf41ac90e914053f0b1b5e.png

readValue():将json字符串转换成java对象  writeValue():把java对象转换成json字符串

这段代码做的工作:

1.会从body中读取出json格式的字符串

{

    "studentId":20,

    "classId":101

}

2. 根据第二个参数类对象,创建Student实例

3.解析上述json格式的字符串,处理成map键值对结构

4.遍历所有的键值对,看key的名字和Student实例的哪个属性名字相匹配,就把对应的value设置到该属性中

5.返回该Student实例

重启服务器,再次发送请求

f5effa550b2e45408422257fadd421c0.png

 控制台打印了body信息b82e475bdc024c5093d94aa777b147c9.png

总结:

1.GET,参数通过query string传递,服务器使用req.getParameter方法获取参数的值

2.POST,参数通过body(form表单的格式传递) ,服务器用req.getParameter方法获取参数的值

3.POST,参数通过body(json格式传递) ,服务器使用getInputStream读取body的值 

 

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

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

相关文章

若依— — 快速入门【源码分析】

若依— — 快速入门 1 什么是若依 官网地址&#xff1a;http://www.ruoyi.vip/ 若依是一款优秀的开源项目&#xff0c;涉及到企业开发中大部分的管理系统&#xff0c;我们依此为模板进行二次开发&#xff0c;可以快速开发出符合大部分公司中的后台管理系统。 2 使用若依 使用开…

Spring Security --- authorizeRequests配置

目录 自定义配置类之访问权限 匹配顺序规则 访问控制包含 访问控制url匹配 访问控制方法 角色、权限判断 使用注解进行角色权限控制 自定义配置类之访问权限 http.authorizeRequests()主要是对url进行访问权限控制通过这个方法来实现url授权操作支持链式写法 匹配顺序…

【react全家桶学习】react简介

react是什么&#xff1f; react是用于构建用户界面的JS库&#xff0c;是一个将数据渲染为HTML视图的开源JS库 谁开发的&#xff1f; 由Facebook开发&#xff0c;且开源 为什么要学&#xff1f; 原生JavaScript操作DOM繁琐、效率低 ( DOM-API操作 UI)使用JavaScript直接操作…

Attention注意力机制

加粗样式通俗理解&#xff1a;你会注意什么&#xff1f; 对于一个模型而言&#xff08;CNN&#xff0c;LSTM&#xff09;&#xff0c;模型本身很难决定什么重要什么不重要&#xff0c;因此注意力机制诞生了。 注意力机制&#xff1a;我们会把焦点聚焦在比较重要的事务上 怎么…

详细聊一聊Android Apk的四代签名

简介 大部分开发者对apk签名还停留在APK v2&#xff0c;对APK v3和APK v4了解很少&#xff0c;而且网上大部分文章讲解的含糊不清&#xff0c;所以根据官网文档重新整理一份。 apk签名从APK v1到APK v2改动很大&#xff0c;是颠覆性的&#xff0c;而APK v3只是对APK v2的一次…

RocketMQ是是如何管理消费进度的?又是如何保证消息成功消费的?

RocketMQ消费者保障 作者: 博学谷狂野架构师GitHub&#xff1a;GitHub地址 &#xff08;有我精心准备的130本电子书PDF&#xff09; 只分享干货、不吹水&#xff0c;让我们一起加油&#xff01;&#x1f604; 消息确认机制 consumer的每个实例是靠队列分配来决定如何消费消息的…

业务异步离线任务平台思考

目录 一、离线任务平台定义 二、实际开发那种的实现方式分析 三、企业应用与链接分享 &#xff08;一&#xff09;具体企业应用举例 &#xff08;二&#xff09;离线任务平台相关文章和论文链接 四、开源代码库参考 一、离线任务平台定义 离线任务平台通常是指一种基于云…

基于 Verilog HDL 设计真彩图的灰度处理模块

引言 FPGA比较擅长的是作定点数整数运算&#xff0c;那么对于带有小数部分的乘加运算。一般都选择先扩大若干倍&#xff0c;而后将运算结果缩小若干倍实现。 应用案例&#xff0c;真彩图转灰度图的心理学计算公式&#xff1a; Gray 0.299R 0.587G 0.114B 本文给出具体的…

Spring boot基础学习之(十八):通过shiro框架使用Mybatis实现用户的认证完整的认证流程

在上几篇文章的基础上&#xff0c;实现本次案例 注意&#xff1a;本篇文章的实现代码在几篇文章都已经详细的讲过了&#xff0c;所以在此篇文章&#xff0c;将不再有理论知识的陈述&#xff0c;更过的流程&#xff0c;如何通过代码实现连接数据库进行认证 添加本次案例所需要的…

【并发编程】ConcurrentHashMap源码分析(二)

addCount 统计元素个数 private transient volatile long baseCount; //初始化大小为2,如果竞争激烈,会扩容 2->4 private transient volatile CounterCell[] counterCells;如果竞争不激烈的情况下&#xff0c;直接用cas (baseCount1)如果竞争激烈的情况下&#xff0c;采用…

项目管理的三要素:时间、成本和质量

项目管理的三要素&#xff1a;时间、成本和质量&#xff0c;他们作为衡量一个项目的成功失败的指标&#xff0c;贯穿项目整个过程。 时间&#xff1a; 项目时间管理包括使项目按时完成必须实施的各项过程。 项目计划按照逻辑关系安排计划活动顺序时&#xff0c;需要考虑进度…

C#,码海拾贝(16)——求行列式值的全选主元高斯消去法,《C#数值计算算法编程》源代码升级改进版

1 高斯消去法 数学上&#xff0c;高斯消元法&#xff08;或译&#xff1a;高斯消去法&#xff09;&#xff0c;是线性代数规划中的一个算法&#xff0c;可用来为线性方程组求解。但其算法十分复杂&#xff0c;不常用于加减消元法&#xff0c;求出矩阵的秩&#xff0c;以及求出…

利好消息不断原油价格大幅走高

​几个OPEC成员国将在年底前将全球产量再削减116万桶/天&#xff0c;这将进一步给央行遏制全球通胀的努力带来负担&#xff0c;但关键是保护该联盟更广泛的产量策略免受政治压力的影响。 华盛顿介入批评了上周日的声明&#xff0c;8个OPEC生产国&#xff08;包括组织的领导国沙…

Java中jar包的创建和使用

Java中jar包的创建和使用 jar包的基本概念 jar包的全称是java archive。jar包本质就是一种压缩包。在Java开发中一般是用来压缩类的一个包。类似C/C中的静态库和动态库&#xff0c;但是又不完全是。 C/C中的静态库和动态库是对中间文件&#xff08;*.o&#xff09;打包成一个…

【电路原理】电路元件基本知识详解

博主简介&#xff1a;努力学习的22级计科生一枚~博主主页&#xff1a; 是瑶瑶子啦所属专栏: 电路理论 前言1.电阻元件2.电容元件3.电感元件4.独立电源4.1&#xff1a;电压源4.2&#xff1a;电流源5.受控电源6.符号补充&#xff1a;7.总结本专栏文章主要总结、归纳电路原理、电路…

数据结构-排序(2)

前言&#xff1a; 上一章节介绍了 排序中的插入排序和选择排序&#xff0c; 分别复盘了插入排序中的直接插入排序和希尔排序以及选择排序中的选择排序和堆排序。今天继续复盘交换排序。 目录 2.3交换排序 2.3.1冒泡排序 2.3.2快速排序 2.3.2快速排序非递归 2.3交换排序 基…

HTML5 <figure> 标签、HTML5 <footer> 标签

HTML5 <figure> 标签 实例 使用 <figure> 元素标记文档中的一个图像&#xff1a; <figure><img src"img_pulpit.jpg" alt"The Pulpit Rock" width"304" height"228"> </figure>尝试一下 浏览器支持 …

在proteus中仿真arduino实现矩阵键盘程序

矩阵键盘是可以解决我们端口缺乏的问题&#xff0c;当然&#xff0c;如果我们使用芯片来实现矩阵键盘的输入端口缺乏的问题将更加划算了&#xff0c;本文暂时不使用芯片来解决问题&#xff0c;而使用纯朴的8根线来实现矩阵键盘&#xff0c;目的是使初学者掌握原理。想了解使用芯…

Lua脚本

目录说明什么是Lua脚本为什么要使用Lua脚本Lua脚本的安装Lua脚本的使用Lua的变量Lua脚本的算术运算符Lua脚本的关系运算符Lua脚本的逻辑运算符Lua脚本不同的操作Lua脚本的函数和标准库Redis整合Lua脚本&#xff08;重点&#xff09;在Java集成Lua在SpringBoot项目中使用Redis集…

前端PC端适配,网页端适配

问题背景 由于我司是使用的大屏&#xff0c;且设计稿尺寸为19201080。但是需要适配各种分辨率&#xff0c; 比如12801024(5:4)、1366768(16&#xff1a;10)、16801050&#xff08;16&#xff1a;10&#xff09;。在尝试了多种方法之后&#xff0c;最终确定主要的适配方法为rem…