Servlet实践操作

Servlet运行原理

  1. Tomcat 的代码内置了 main 方法,当我们启动 Tomcat 的时候,就是从 Tomcat 的 main 方法开始执行的

  2. 被 @WebServlet 注解修饰的类会在 Tomcat 启动的时候就被获取并集中管理

  3. Tomcat 通过反射这样的语法机制来创建被 @WebServlet 注解修饰的类的实例

  4. 这些实例被创建完之后,就会调用其中的 init 方法进行初始化

  5. 这些实例被销毁之前,就会调用其中的 destory 方法进行收尾工作

  6. Tomcat 内部也是通过 Socket API 进行网络通信

  7. Tomcat 为了能够同时处理多个 HTTP 请求,采取了多线程的方式实现,因此 Servlet 是运行在多线程环境下的

 Post请求测试

浏览器直接发送的是get请求,这里使用Postman进行接口测试

@WebServlet("/testDoPost")
public class TestDoPostServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("testPost success!");}
}

 Response重定向到其他页面

public class RedirectServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.sendRedirect("https://blog.csdn.net/weixin_44610169");}
}

post请求体body中携带信息获取

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

body内容格式为JSON数据获取

JSON格式的数据需要解析,Java内置库没有对JSON的解析,所以这里导入第三方数据库jackson,使用jackson解析读取请求中body内的数据.

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.17.1</version></dependency>

 

//定义一个JavaBean类
class UserInfo{public String username;public String password;
}
//读取请求中所有bodypublic String readBody(HttpServletRequest req) throws IOException {//获取请求体长度int contentLength = req.getContentLength();//获取请求体内容byte[] bytes = new byte[contentLength];//读取请求体内容ServletInputStream inputStream = req.getInputStream();//将请求体内容读取到bytes中inputStream.read(bytes);//将bytes转换为字符串返回return new String(bytes, StandardCharsets.UTF_8);}
@WebServlet("/jsonParameter")
public class JsonParameterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=UTF-8");//读取请求体内容String body = readBody(req);//将请求体内容转换为JavaBean对象UserInfo userInfo = new ObjectMapper().readValue(body, UserInfo.class);//输出解析结果resp.getWriter().write("username: " + userInfo.username);resp.getWriter().write("password: " + userInfo.password);}
}

 Cookie

  • Cookie 是什么?

Cookie 是浏览器提供的在客户端存储数据的一种机制(由于浏览器禁止了网页中的代码直接访问本地磁盘的文件,因此想要在网页中实现持久化存储,就可以通过 Cookie 这样的机制)

  • Cookie 里面存什么?

Cookie 存储的数据都是程序员自定义的,存储的数据是一个字符串,是键值对结构的,键值对之间使用 ; 分割,键和值之间使用 = 分割

  • Cookie 从哪里来?

服务器返回响应的时候,可以把要在客户端保存的数据以 Set-Cookie 这个 header 的方式返回给浏览器

  • Cookie 到哪里去?

客户端下次访问服务器的时候,就会把之前保存好的 Cookie 再发送给服务器

  • Cookie 的典型应用场景:

可以使用 Cookie 来保存用户的登录信息。比如我们登录过某个网站后,下次登录时就不需要重新输入用户和密码了

  • Cookie 的缺陷:

每次请求都要把该域名下所有的 Cookie 通过 HTTP 请求传给服务器,因此 Cookie 的存储容量是有限的。

Session

在计算机中,尤其是在网络应用中,Session 称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在 Session 对象中。注意会话状态仅在支持 Cookie 的浏览器中保留。

session的本质

  • 会话的本质就是一个哈希表,其中存储了一些键值对结构,key 叫做 sessionId,是一个不随机的、不重复的、唯一的字符串,value 就是要保存的身份信息,通过 HttpSession 对象来保存。key 和 value 都是 Servlet 自动创建的。

  • 每个用户登录都会生成一个会话,服务器会以哈希表的方式将这些会话管理起来

  • 一个会话的详细数据通过一个 HttpSession 对象来存储,并且 HttpSession 对象中存储的数据也是键值对结构,key 和 value 都是程序员自定义的

  • 当用户成功登录之后,服务器在 Session 中会生成一个新的记录,并把 sessionId 返回给客户端(例如 HTTP 响应中可以通过 Set-Cookie 字段返回,其中 Cookie 的 key 为 “JSESSION”,value 为服务器生成的 sessionId 的具体的值)

  • 然后客户端只需要保存这个 sessionId ,当后续再给服务器发送请求时,请求中就会带上 sessionId(例如 HTTP 请求中会带上 Cookie 字段用于传递 Session)

  • 服务器收到请求后,就会根据请求中的 sessionId 在 Session 中查询对应用户的身份信息,在进行后续操作

 Servlet实现登录测试

前端页面login.html使用form表单发送数据,servlet接收后进行操作

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Login</title>
</head>
<body><form action="/servlet_test/login1" method="post"><input type="text" placeholder="用户名" name="username"/><input type="password" placeholder="密码" name="password"/><input type="submit" value="登录"></form></body>
</html>
@WebServlet("/login1")
public class loginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");String username = req.getParameter("username");String password = req.getParameter("password");if (username == null || username.isEmpty() || password == null || password.isEmpty()){resp.getWriter().write("<h3>用户名或密码不能为空</h3>");return;}if (!username.equals("root") && !password.equals("root")){resp.getWriter().write("<h3>用户名或密码错误</h3>");return;}if (username.equals("root") && password.equals("root")){// 登录成功后创建sessionHttpSession session = req.getSession(true);session.setAttribute("visitCount", 0);// 登录成功后跳转页面resp.sendRedirect("index");}}
}
@WebServlet("/index")
public class LoginSuccessServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");HttpSession session = req.getSession(false);if(session == null){// 如果为空重定向到登录页面resp.sendRedirect(req.getContextPath() + "/login.html");return;}// 登录成功后获取session中的数据Integer visitCount = (Integer) session.getAttribute("visitCount");visitCount += 1;session.setAttribute("visitCount", visitCount);resp.getWriter().write("登录成功,欢迎回来!您已经登录" + visitCount + "次!");}
}

文件上传

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>上传文件</title>
</head>
<body>
<!--通过 form 表单构造上传文件,要加上一个 enctype 字段,它表示 body 中的数据格式,它的默认值为:x-www-form-urlencoded,这里要修改成:multipart/form-data,它是上传文件或者图片的数据格式--><form action="/servlet_test/uploadFile" method="post" enctype="multipart/form-data">><input type="file" name="file1"><input type="submit" value="上传"></form>
</body>
</html>
@MultipartConfig
@WebServlet("/uploadFile")
public class uploadFileServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=UTF-8");Part file1 = req.getPart("file1");String fileName = file1.getSubmittedFileName();String contentType = file1.getContentType();long size = file1.getSize();System.out.println("文件名:" + fileName + ",文件类型:" + contentType + ",文件大小:" + size + "字节");file1.write("C:\\Users\\86152\\Desktop\\" + fileName);resp.getWriter().write("文件上传成功");}
}
传文件操作还需要给 Servlet 加上一个 @MultipartConfig 注解,否则服务器代码无法使用 getPart() 方法

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

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

相关文章

PCB设计隐藏的陷进

1、BGA芯片的开窗和过油设计。 加工工艺中&#xff0c;范式过孔都需要盖油设计&#xff0c;实心焊盘需要开窗设计&#xff0c;坚决不能盖油。 2、通孔设计的互联连通性 比如H3芯片的wifi设计&#xff0c;实际上是没有联通的&#xff0c;虽然四层板的中间层有焊盘&#xff0c;但…

【FreeRTOS】估算栈的大小

参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》 目录 估算栈的大小回顾简介计算说明估计函数用到的栈有多大合计 估算栈的大小 回顾 上一篇文章链接&#xff1a;http://t.csdnimg.cn/Cc8b4 传送门: 上一篇文章 上一篇文章创建的三个任务 /* 创建任务&#xff1a;声 *…

LabVIEW开发为何仿制(致敬)经典成熟软件

​仿制&#xff08;致敬&#xff09;成熟软件进行LabVIEW开发更方便&#xff0c;因其提供了稳定的架构和结构、优化的用户体验和界面设计、技术规范和标准、稳定性和可靠性。结合用户手册和现有操作进行仿制&#xff0c;就像小米致敬保时捷一样&#xff0c;可以提高开发效率、降…

vivado SITE

描述 SITE是一个设备对象&#xff0c;表示许多不同类型的逻辑资源之一 可在目标Xilinx FPGA上获得。 SITE包括SLICE/CLB&#xff0c;它们是基本逻辑元件&#xff08;BEL&#xff09;的集合&#xff0c;如 查找表&#xff08;LUT&#xff09;、触发器、多路复用器&#xff0c;携…

QT/基于TCP的服务端实现

代码 widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget),p(new QTcpServer(this))//给服务器指针申请空间 {ui->setupUi(this); }Widget::~Widget() {delete ui; }void W…

实测:三款垃圾CPU推理Llama3 8B

经常有一些朋友问我本地运行大模型的电脑需要什么样的配置。其实一些常用大模型的运行需要的硬件并不像我们想象的那样高不可攀。不要被那些复杂的技术术语所吓倒&#xff0c;关键在于亲自动手尝试。 “不试&#xff0c;怎么知道呢&#xff1f;” 这句话道出了真理。今天&#…

【Linux】基础IO_1

文章目录 六、基础IO1. C语言的文件接口2. 系统文件I/O 未完待续 六、基础IO 1. C语言的文件接口 我们知道 文件 文件内容 文件属性 。即使是一个空文件&#xff0c;仍然会在磁盘中占据空间。那打开文件是什么意思呢&#xff1f;其实文件打开的意思就是&#xff1a;将文件从…

力扣每日一题 6/19 排序+动态规划

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;IT竞赛 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 2713.矩阵中严格递增的单元格数【困难】 题目&#xff1a; 给你一个下标从…

【学习DayNa】信息系统开发整理

✍&#x1f3fb;记录学习过程中的输出&#xff0c;坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;指点&#x1f64f; 结构化方法 结构是指系统内各个组成要素之间的相互联系、相互作用的框架。结构化开发方法就是…

shell中的流程控制

条件判断在流程控制中的重要性 有了条件判断才能进行if判断即分支流程&#xff0c;才能进行case的多分支流程&#xff0c;才能进行for循环和while循环。 单分支流程判断 如上图所示&#xff0c;在shell编程中常使用英文状态下的分号来在Linux控制台一次性执行多条命令&#x…

小米SU7遇冷,下一代全新车型被官方意外曝光

不知道大伙儿有没有发现&#xff0c;最近小米 SU7 热度好像突然之间就淡了不少&#xff1f; 作为小米首款车型&#xff0c;SU7 自上市以来一直承载着新能源轿车领域流量标杆这样一个存在。 发售 24 小时订单量破 8 万&#xff0c;2 个月后累计交付破 2 万台。 看得出来限制它…

运算放大器(运放)缓冲器(跟随器)电路

运算放大器(Operational Amplifier) 运算放大器(Operational Amplifier)是一种差分放大器&#xff0c;具有高输入电阻、低输出电阻、高开放增益&#xff08;开环增益&#xff09;&#xff0c;并具有可放大输入引脚与-输入引脚间的电压差的功能。 设计目标 输入输入输出输出频…

HTML李峋同款跳动的爱心代码(双爱心版)

目录 写在前面 跳动的爱心 完整代码 代码分析 系列推荐 最后想说 写在前面 在浩瀚的网络世界中&#xff0c;总有一些小惊喜能触动我们的心弦。今天&#xff0c;就让我们用HTML语言&#xff0c;探索既神秘又浪漫的李峋同款跳动的爱心代码吧。 首先&#xff0c;让我们一起…

基于Pytorch框架的深度学习Swin-Transformer神经网络食物分类系统源码

第一步&#xff1a;准备数据 5种鸟类数据&#xff1a;self.class_indict ["苹果派", "猪小排", "果仁蜜饼", "生牛肉薄片", "鞑靼牛肉"] &#xff0c;总共有5000张图片&#xff0c;每个文件夹单独放一种数据 第二步&…

swift使用swift-protobuf协议通讯,使用指北

什么是Protobuf Protobuf&#xff08;Protocol Buffers&#xff09;协议&#x1f609; Protobuf 是一种由 Google 开发的二进制序列化格式和相关的技术&#xff0c;它用于高效地序列化和反序列化结构化数据&#xff0c;通常用于网络通信、数据存储等场景。 为什么要使用Proto…

Java面试八股之myBatis与myBatis plus的对比

myBatis与myBatis plus的对比 基础与增强&#xff1a; MyBatis 是一个成熟的Java持久层框架&#xff0c;它允许开发者通过XML文件或注解来配置SQL语句和数据库映射&#xff0c;提供了一个灵活的方式来操作数据库&#xff0c;但需要手动编写所有的SQL语句和结果集映射。 MyBa…

Day55 代码随想录打卡|二叉树篇---二叉搜索树中的插入操作

题目&#xff08;leecode T701&#xff09;&#xff1a; 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值…

【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【11】ElasticSearch

持续学习&持续更新中… 守破离 【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【11】ElasticSearch 简介基本概念ElasticSearch概念-倒排索引安装基本命令ik 分词器SpringBoot整合测试存储数据&#xff1a;测试复杂检索同步与异步调用 参考 简介 Elasticsearch 是一…

【AIGC】MetaGPT原理以及应用

目录 MetaGPT原理 MetaGPT应用 MetaGPT和传统编程语言相比有什么优势和劣势 视频中的PPT 参考资料 MetaGPT原理 MetaGPT是一种多智能体框架&#xff0c;它结合了元编程技术&#xff0c;通过标准化操作程序&#xff08;SOPs&#xff09;来协调基于大语言模型的多智能体系统…

嵌入式实验---实验一 通用GPIO实验

一、实验目的 1、掌握STM32F103 GPIO程序设计流程&#xff1b; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、通过按键实现&#xff1a;按键按下&#xff0c;LED点亮&#xff1b;按键释放&#xff0c;LED熄灭。 三、实验设备和器材 电脑、Keil uVision5软件、Proteus…