【JavaEE初阶】Servlet (二) Servlet中常用的API
文章目录
- HttpServlet
- 核心方法
- HttpServletRequest
- 核心方法
- HttpServletResponse
- 核心方法
Servlet中常用的API有以下三个:
HttpServlet
HttpServletRequest
HttpServletResponse
HttpServlet
我们写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet
, 并重写其中的某些方法.
核心方法
方法名称 | 调用时机 |
---|---|
init(初始化) | 在 HttpServlet 实例化之后被调用一次 |
destory(销毁) | 在 HttpServlet 实例不再使用的时候调用一次 |
service | 收到 HTTP 请求的时候调用 |
doGet | 收到 GET 请求的时候调用(由 service 方法调用) |
doPost | 收到 POST 请求的时候调用(由 service 方法调用) |
doPut/doDelete/doOptions/… | 收到其他请求的时候调用(由 service 方法调用) |
说明:
init
:tomcat首次收到和该类相关联的请求时触发.(类似于前面学的懒汉模式).例如:
tomcat收到 /hello 的路径请求,就会调用到HelloServlet进行实例化,于是就需要先对helloServlet进行实例化.(实例化只进行一次). 后续再收到 /hello,就不必重复实例化了,直接复用之前的HelloServlet实例即可.destroy
:通过重写我们可以看到:service
:收到http请求就会触发(路径匹配请求).
以上三个方式是HTTPServlet最关键的三个方法.
面试题:Servlet的声明周期是什么?
- 开始的时候,执行init
- 每次收到请求的时候,执行service
- 销毁之前,执行destroy
在浏览器中直接输入URL
可以看到doGet
请求:
那么其他请求怎么构造呢?
- 可以使用
Postman
.
同时我们可以服务器处看到日志:
- 使用ajax构造请求
注意文件创建位置.
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><!-- 构造ajax请求访问服务器 --><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js"></script><script>$.ajax({type:'get',url:'method',success:function(body,status){console.log(body);}})</script>
</body>
</html>
上述代码中url:'method'
是相对路径.url:"/hello_servlet/method"
是绝对路径.(浏览器中的要求) 注意两种路径的写法.还有在@WebServlet("/hello")
这个注解中,这个路径必须/
开头,但是并非表示绝对路径(Servlet中的要求)
HttpServletRequest
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(Stringname) | 返回一个字符串对象的数组,包含所有给定的请求参数的值,如果参数不存在则返回 null。 |
Enumeration getHeaderNames() | 返回一个枚举,包含在该请求中包含的所有的头名。 |
String getHeader(Stringname) | 以字符串形式返回指定的请求头的值。 |
String getCharacterEncoding() | 返回请求主体中使用的字符编码的名称。 |
String getContentType() | 返回请求主体的 MIME 类型,如果不知道类型则返回 null。 |
int getContentLength() | 以字节为单位返回请求主体的长度,并提供输入流,或者如果长度未知则返回 -1。 |
InputStream getInputStream() | 用于读取请求的 body 内容. 返回一个 InputStream 对象 |
说明:
query String
是键值对结构,使用getParameter
就可以根据key
获取到value
.
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 {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html");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>");resp.getWriter().write(stringBuilder.toString());}
}
前端给后端传参的三种方式 :
- GET,queryString
- POST,from
- POST,json
- GET,queryString
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("/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; charset=utf8");// resp.setCharacterEncoding("utf8");resp.getWriter().write("学生id = " + studentId + " 班级id = " + classId);}
}
如果key在queryString中不存在,此时就返回null
.
- POST,from
对于前端from表单这样的数据结构,后端还是使用GetParameter来获取.注意,from表单也是键值对,和queryString的格式一样,只是这部分内容在body中
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><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><!-- 构造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>
使用getparameter
既可以获取到queryString
键值对,也可以获取到form
表单构造的body
中的键值对.
上述过程,是前后端交互的过程.
3. POST,json
json是一种非常主流的数据结构,也是键值对结构
使用Postman构造POST:
下面写PostParameter2服务器代码:
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.io.InputStream;@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);}
}
打开Postman发送请求,在日志可以看到:
打开fiddler抓包可以看到:
小结:
当前通过json传递数据,但是服务器这边只是把整个body读取进来,并没有按照键值对的方式来处理(还不能根据key获取value),此时可以使用第三方库来解决这个问题.
打开maven中央仓库:
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;
import java.io.InputStream;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 {// 使用 jackson 涉及到的核心对象.ObjectMapper objectMapper = new ObjectMapper();// readValue 就是把一个 json 格式的字符串转成 Java 对象.Student student = objectMapper.readValue(req.getInputStream(), Student.class);System.out.println(student.studentId + ", " + student.classId);//resp.getWriter().write(body);}
}
- 会从body中读取json格式的字符串
- 根据第二个参数类对象,创建Student实例
- 解析上述json格式的字符串,处理成map键值对结构
- 遍历所有键值对,看键的名字和student实例中那个属性名字匹配,就把对应的value设置到该属性中.
- 返回该Student实例
如果请求中多一个参数,Student中没有,则会出现500 服务器内部错误.
如果请求中少一个参数,Student中有这个参数,则会返回默认值.
HttpServletResponse
Servlet 中的 doXXX 方法的目的就是根据请求计算得到相应, 然后把响应的数据设置到
HttpServletResponse 对象中.
然后 Tomcat 就会把这个 HttpServletResponse
对象按照 HTTP 协议的格式, 转成一个字符串, 并通过Socket 写回给浏览器.
核心方法
方法 | 描述 |
---|---|
void setStatus(int sc) | 为该响应设置状态码。 |
void setHeader(String name,String value) | 设置一个带有给定的名称和值的 header. 如果 name 已经存在,则覆盖旧的值. |
void addHeader(Stringname, 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 中写入二进制格式数据. |
说明:
sendRedirect
重定向.
两种写法:
@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendRedirect("https://www.baidu.com");}
}
@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setStatus(302);resp.setHeader("Location","https://www.baidu.com");}
}
启动服务器,在地址栏中输入http://127.0.0.1:8080/hello_servlet/redirect
可以看到网页跳转至百度页面:
使用fiddler可以看到:
上述GET请求触发resp.sendRedirect("https://www.baidu.com");
代码,从而得到响应:
相关文章:

【JavaEE初阶】Servlet (二) Servlet中常用的API
文章目录 HttpServlet核心方法 HttpServletRequest核心方法 HttpServletResponse核心方法 Servlet中常用的API有以下三个: HttpServletHttpServletRequestHttpServletResponse HttpServlet 我们写 Servlet 代码的时候, 首先第一步就是先创建类, 继承自 HttpServlet, 并重写其…...

redis 存储原理与数据模型
文章目录 一、redis的存储结构1.1 存储结构1.2 存储转换 二、字典(dict)实现2.1 数据结构2.2 哈希冲突2.3 扩容2.4 缩容2.5 渐进式rehash2.6 scan 命令2.7 expire机制 三、跳表(skiplist)实现3.1 理想跳表3.2 redis跳表 一、redis的存储结构 1.1 存储结构 1.2 存储转换 二、字…...

初识mysql数据库之事务的隔离性
目录 一、理解隔离性 二、隔离级别 1. 不同的隔离级别的简单概述 2. 查看隔离级别 2.1 查看全局隔离级别 2.2 查看会话隔离级别 3. 设置隔离界别 4. 读未提交(Read Uncommitted) 4.1 读未提交测试 5. 读提交(Read Committed&#x…...

今天学学消息队列RocketMQ:消息类型
RocketMQ支持的消息类型有三种:普通消息、顺序消息、延时消息、事务消息。以下内容的代码部分都是基于rocketmq-spring-boot-starter做的。 普通消息 普通消息是一种无序消息,消息分布在各个MessageQueue当中,以保证效率为第一使命。这种消息…...

小程序附件下载并预览功能
一、实现的功能: 1、word、excel、图片等实现下载并预览 2、打开文件后显示文件名称 二、代码: // 判断文件类型whatFileType(url) {let sr url.lastIndexOf("."); // 最后一次出现的位置let fileType url.substr(sr 1); // 截取url的…...

数据库缓存服务——NoSQL之Redis配置与优化
目录 一、缓存概念 1.1 系统缓存 1.2 缓存保存位置及分层结构 1.2.1 DNS缓存 1.2.2 应用层缓存 1.2.3 数据层缓存 1.2.4 硬件缓存 二、关系型数据库与非关系型数据库 2.1 关系型数据库 2.2 非关系型数据库 2.3 关系型数据库和非关系型数据库区别: 2.4 非…...

【雕爷学编程】MicroPython动手做(13)——掌控板之RGB三色灯
知识点:什么是掌控板? 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片,支持WiFi和蓝牙双模通信,可作为物联网节点,实现物联网应用。同时掌控板上集成了OLED…...

.Net Core上传组件_.Net Core图片上传组件_Uploader7.0
一、.Net Core上传组件Uploader7.0简介 1.当前版本v7.0,前端框架丰富升级 2.前端jquery框架封装,cover.js, 腾讯云cos-js-sdk-v5.min.js 3.后端,支持Asp.Net 和 Asp.Net Core 矿建 4.数据传输模式支持:WebScoket 、Ajax、Form 模式上传到…...

Exadata磁盘损坏导致磁盘组无法mount恢复(oracle一体机磁盘组异常恢复)---惜分飞
Oracle Exadata客户,在换盘过程中,cell节点又一块磁盘损坏,导致datac1磁盘组(该磁盘组是normal方式冗余)无法mount Thu Jul 20 22:01:21 2023 SQL> alter diskgroup datac1 mount force NOTE: cache registered group DATAC1 number1 incarn0x0728ad12 NOTE: ca…...

左值引用与右值引用的区别?右值引用的意义?
左值引用与右值引用的区别?右值引用的意义? 1 区别1.1 功能差异1.2 左值引用1.3 右值引用1.3.1 实现移动语义1.3.2 实现完美转发 2 引用的作用3 区分左值和右值3.1 左值3.2 右值 1 区别 左值引用是对左值的引用;右值引用是对右值的引用。 &…...

2023年深圳杯数学建模D题基于机理的致伤工具推断
2023年深圳杯数学建模 D题 基于机理的致伤工具推断 原题再现: 致伤工具的推断一直是法医工作中的热点和难点。由于作用位置、作用方式的不同,相同的致伤工具在人体组织上会形成不同的损伤形态,不同的致伤工具也可能形成相同的损伤形态。致伤…...

Vue的router学习
,前端路由的核心是什么呢?改变URL,但是页面不进行整体的刷新。 vue-router是基于路由和组件的 路由用于设定访问路径, 将路径和组件映射起来; 在vue-router的单页面应用中, 页面的路径的改变就是组件的切换; 使用router需要…...

Inpaint Anything: 自动化抹除视频元素
自动化抹除视频元素 不用逐帧抠图,直接SAM Tracking Video Inpainting就能实现自动化抹除奔跑吧idol。 https://github.com/geekyutao/Inpaint-Anything 目录 网站演示参考文献 网站 https://huggingface.co/spaces/InpaintAI/Inpaint-Anything 演示 原理就是&a…...

Flutter 开发者工具 Android Studio 开发Flutter应用
Flutter 开发者工具 在 Android Studio 开发Flutter应用 🔥 Android Studio 版本更新 🔥 Android Studio Check for Update Connection failed 解决方案 如果是运行的是32位的android studio需要在andriod studio的启动目录下找到studio.exe.vmoptio…...

后端byte[]传给前端接收默认变成string字符串
创建时间:2023.7.28 建议:最好直接用字符串,我是没办法要求保密,存取都是字符串,程序里面是byte数组 既然他到前端会转换成字符串那么就是被转码了 那我们反向转码就好了 这是在后端处理,反正前端也是乱…...

UE5 动画蓝图模板(Animation Blueprint Template)
文章目录 前言准备内容创建动画蓝图使用动画蓝图模板示例1示例2总结前言 本文基于虚幻5.2版本介绍制作动画蓝图模板,本教程要求使用虚幻5.0及以上版本。 准备内容 使用第三人称游戏内容包,已添加可忽略。 选择第三人称游戏,添加到项目。 创建动画蓝图 在 Characters 文件…...

Log4j源码解析
Log4j源码解析 主要流程 Logger logger Logger.getLogger(Main.class); 1、通过Logger.getLogger(Class clazz) 或 Logger.getLogger(String name)进入。 2、加载LogManager进jvm, 执行静态代码块执行初始化, 创建出RepositorySelector实例及LoggerRepository实例(Hierarchy…...

Docker 容器访问宿主机服务
docker 网络简介 docker 在安装时会默认创建三个网络:bridge(默认网络模式)、 none 、host。 host 直接和宿主机共用网络。bridge 网络隔离,通过虚拟网桥(一般是 docker0)与宿主机通信。none 禁用网络功能…...

Go 发送邮件
要在Go中发送电子邮件,您可以使用第三方库,如 gomail 。以下是一个使用 gomail 发送电子邮件的示例代码: package main import ("fmt""gopkg.in/gomail.v2" ) func main() {// 创建邮件消息m : gomail.NewMessage()m.Se…...

Spring AOP 的概念及其作用
一、什么是 Spring AOP? 在介绍 Spring AOP 之前,首先要了解一下什么是 AOP ? AOP ( Aspect Oriented Programming ):面向切面编程,它是一种思想, 它是对某一类事情的集中处 理 。…...

python基础1——环境安装
文章目录 一、Windows安装二、Linux安装三、pycharm安装3.1 软件安装3.2 个性化设置3.3 基本使用3.3.1 定义变量3.3.2 查看数据类型3.3.3 运算符3.3.4 操作符3.3.5 转义符 一、Windows安装 1、下载软件安装包,官网 2、开始安装。 2.查看是否安装成功。 3.安装…...

uniapp 中 的progress加载进度条 的使用,在 页面显示数据加载的进度条,使用户的使用体验效果更好
学习目标: 学习目标如下: 例如: uniapp 中 的progress加载进度条 的使用,在 页面显示数据加载的进度条,使用户的使用体验效果更好 学习内容: 学习内容如下所示: 相关属性的说明 进度条的显…...

【尚硅谷】第01章:随堂复习与企业真题(Java语言概述)
来源:尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备) 基本都是宋老师发的资料里面的内容,只不过补充几个资料里没直接给出答案的问题的答案。 不想安装markdown笔记的app所以干脆在这里发一遍。 第01章:随堂复习…...

MyBatis的SqlSession理解
SqlSession是Mybatis最重要的构建之一,可以认为Mybatis一系列的配置目的是生成类似JDBC生成的Connection对象的statement对象,这样才能与数据库开启“沟通”,通过SqlSession可以实现增删改查(当然现在更加推荐是使用Mapper接口形式…...

axios 某个接口使用自己独有的完整地址
可以在axios请求中使用完整的URL,而不使用baseURL, 只需将url字段设置为完整的URL即可 import axios from axios;export function getInfo() {return axios({url: http://192.168.3.15:8086/test/messages,method: post}); }直接在url字段中提供了完整的…...

WEB:Web_python_template_injection
背景知识 python模板注入 ssit 题目 打开题目,发现页面提示,翻译为python模板注入 先测试是否存在注入 可以发现被执行了 先查看所有的子类 payload {{[].__class__.__base__.__subclasses__()}} 利用site.Printer的os模块执行命令 payload {{.__…...

【Android安全】Embedded Trace Microcell模块
ETM: Embedded Trace Macrocell, hardware unit responsible to generate hardware instruction trace. ETM模块用于在硬件层面实现instruction trace,可用于辅助逆向分析。 使用教程: https://mcuoneclipse.com/2016/11/05/tutorial-getting-etm-inst…...

修改内核驱动之后-如何给内核打补丁
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言思路步骤1.进入下面路径2.修改文件calibrate.c3.使用git工具生产补丁文件4.移动补丁文件到自己的Linux的recipem目录下总结前言 本文来学习如何使用YOCTO修改Linux内核驱动之后,如何通过打补…...

【javaSE】 类和对象详解
目录 面向对象的初步认知 什么是面向对象 面向对象与面向过程 类定义和使用 简单认识类 类的定义格式 注意事项 练习定义类 定义一个狗类 定义一个学生类 注意事项 类的实例化 什么是实例化 注意事项 类和对象的说明 this引用 为什么要有this引用 什么是this引…...

大数据课程D5——hadoop的Sink
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 掌握Sink的HDFS Sink; ⚪ 掌握Sink的Logger Sink; ⚪ 掌握Sink的File Roll Sink; ⚪ 掌握Sink的Null Sink; ⚪ 掌握Si…...