Java EE Servlet之服务器版表白墙

2023-12-31 11:28

本文主要是介绍Java EE Servlet之服务器版表白墙,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 1. 准备工作
  • 2. 约定前后端交互接口
  • 3. 编写提交消息
  • 4. 数据存入文件
  • 5. 引入数据库

1. 准备工作

我们要把表白墙程序修改成服务器版本
这样即使页面关闭, 表白墙的内容也不会丢失

此处,服务器要实现的功能,主要是两个方面:

  1. 页面加载的时候,网页要从服务器这里获取到当前表白数据
    (让网页端给服务器发起 http 请求,服务器返回响应里就带着刚才的这些数据)
  2. 点击提交的时候,网页就要把用户输入的信息,发送给服务器这面,服务器扶着保存

在一个网站中,服务器起到最主要的效果,往往就是“存储数据”
因此服务器这边往往也就需要能够提供两种风格的接口,存数据,取数据

2. 约定前后端交互接口

服务器这边就需要给网页提供两个 http 的接口

1)获取消息
网页加载的时候,给服务器发送一个 ajax 请求

请求:
GET/message

响应:
HTTP/1.1 200 OK
Content-Type: application/json
在这里插入图片描述
此处的请求和响应的细节,都是可以随意设计的,只要能达成效果

2)提交消息
用户点击 提交 按钮的时候 ajax 给服务器器发送一个请求
目的是为了把用户咋输入框输入的内容,给发送给服务器
在这里插入图片描述

正式编写代码之前,一定要把前后端交互的接口给确定下来
这个就是后续编写代码的依据

编写前端代码:
构造 HTTP 请求(请求是什么样子的)
解析 HTTP 响应(响应是什么样子的)

编写后端代码:
解析 HTTP 请求(请求是什么样子的)
构造 HTTP 响应(响应是什么样子的)

这些都是需要设计好前后端交互接口才嫩个回答的问题

这个过程,就是 自定义应用层协议

3. 编写提交消息

  1. 先写前端代码,发送请求
  2. 再写后端代码,解析请求,构造响应
  3. 再写前端代码,解析响应

我们需要把 网页 放入到 webapp 目录里

tomcat 这样的项目,可以包含一些 html、css、js
这些内容都是在 webapp 目录中

在这里插入图片描述

在这里插入图片描述


编写前端代码,发送 http post 请求
在这里插入图片描述

使用 ajax,需要先引入 jquery 这个库
在这里插入图片描述
前端引入第三方库,往往就是通过 script 标签,写一个地址即可

这个代码在点击按钮的回调函数中
会在点击按钮之后被调用
在这里插入图片描述
前端 ajax 请求,url 路径,写作“message”,前面不带 / ,此时这是一个相对路径的写法

后端处理 ajax 请求,url 路径,写作“/message”,前面带 / ,此时是 Servlet 要求的写法


服务器读取上述请求,并计算出响应

要确定 java 代码中,类的属性的名字 和 json 中的属性的名字保持一致
在这里插入图片描述
在这里插入图片描述


回到前端代码,处理服务器返回的响应

在这里插入图片描述
此处 success 回调函数,不是立即执行的,而是在浏览器收到服务器返回的,成功,这样的响应的时候,才会执行到 function

这个函数的第一个参数,就是响应数据的 body 中的内容
在这里插入图片描述
为了和请求对的上
一般,服务器返回的时候,也是用 json 格式
在这里插入图片描述

在这里插入图片描述


在这里插入图片描述

服务器收到的请求
在这里插入图片描述
浏览器收到的响应
在这里插入图片描述
用 抓包工具查看
在这里插入图片描述

在这里插入图片描述
在代码中写的是一个 相对路径
在这里插入图片描述
最终发送的请求,会被转成绝对路径
就是把相对路径前面,品尚当前 html 所在的 context path 里

响应数据
在这里插入图片描述

4. 数据存入文件

当前已经把 数据提交到服务器保存了
目前还是需要能够把 服务器的数据 拿回到 客户端页面上,并显示

为什么还要从服务器拿小希?

  1. 当前界面上显示的数据,也是在浏览器内存中报讯的,刷新界面/关闭的重新打开 数据就没了
  2. 其他客户端打开页面也是有数据的

这个时候,就需要在页面加载的时候,发起请求

1)客户端在页面加载的时候,发起一个 http 请求
在这里插入图片描述
2)服务器收到这个请求,要处理这个请求并生成响应
在这里插入图片描述

服务器收到的每条消息,都转换成了 Message 对象,放到上述 List 中了
返回的结果,也就是这个 List 的数据
需要把 List 里的每个 Message 取出来,转成 json 字符创,最终拼到一起,得到了响应结果
在这里插入图片描述

jackson 看到了 messageList 是一个 List 类型
转成的json 字符串就是一个 json 数组[]
jackson 自动遍历 List 里的每个元素把每个元素,分别都转成 json 字符串
在这里插入图片描述

确保这几个代码的执行顺序 setStatus 和 setContentType 必须在 getWriter 前面
否则可能不会生效(构造出一个非法的 http 响应报文)
这个事情可以认为是 Servlet bug

3)客户端收到响应,就需要针对响应数据进行解析处理
把响应中的信息,构造成页面元素(html片段),并显示出来

这段代码中,需要拼接出 html 片段
在这里插入图片描述
body 就是服务器返回的响应
数据 json 格式的数组

当响应中,header 带有 Content-Type: application/jsonjquery
就会自动的把 json 字符串,解析成 js 对象了

如果没有带 Content-Type: application/json
就需要通过 js 代码 JSON.parse 方法来手动把 json 字符串转成js 对象

在这里插入图片描述
此时,响应数据中,带有 content type 的
所以此时 jquery 自定帮我们完成解析了

当下 body 就已经是一个 js 对象了(数组对象)

这个就是要构造的内容
在这里插入图片描述
构造出来后,加到这个后面
在这里插入图片描述

在这里插入图片描述
通过类选择器,针对 class 属性进行选择
在这里插入图片描述
html 中的每一个元素/标签,都存在一个 js 的对应的对象,来表示
称为 DOM(文档对象模型)

5. 引入数据库

如何把消息数据存储到数据库中
把数据库引入到代码中

1)引入数据库的依赖

2)建库建表
建库建表,需要用到 sql,都可以写到 文件 中,后续如果需要把表啥的往其他的机器上迁移,建表操作就会比较方便

3)编写数据库代码

import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;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 javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;class Message {public String from;public String to;public String message;@Overridepublic String toString() {return "Message{" +"from='" + from + '\'' +", to='" + to + '\'' +", message='" + message + '\'' +'}';}
}@WebServlet("/message")
public class MessageServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();// 引入数据库, 此时 messageList 就不再需要了.// private List<Message> messageList = new ArrayList<>();private DataSource dataSource = new MysqlDataSource();@Overridepublic void init() throws ServletException {// 1. 创建数据源((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/message_wall?characterEncoding=utf8&useSSL=false");((MysqlDataSource) dataSource).setUser("root");((MysqlDataSource) dataSource).setPassword("123456");}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 读取前端发来的数据, 把这个数据保存到服务器这边.Message message = objectMapper.readValue(req.getInputStream(), Message.class);System.out.println("请求中收到的 message: " + message);// 最简单的办法, 直接在内存中保存. 可以使用一个集合类, 把所有收到的 message 都存到内存中.// 很明显, 保存到内存, 并非是一个非常合理的办法. 后续一旦重启服务器, 数据丢失了.// 相比之下, 把这个数据持久化存储到数据库中, 更科学的.// messageList.add(message);// 插入数据库try {save(message);} catch (SQLException e) {throw new RuntimeException(e);}// 返回一个响应resp.setStatus(200);resp.getWriter().write("ok");// resp.setContentType("application/json");// resp.getWriter().write("{ ok: true }");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 通过这个方法来处理当前获取消息列表的 get 请求. 不需要解析参数, 直接返回数据即可.resp.setStatus(200);resp.setContentType("application/json; charset=utf8");// 从数据库查询List<Message> messageList = null;try {messageList = load();} catch (SQLException e) {throw new RuntimeException(e);}String respJson = objectMapper.writeValueAsString(messageList);resp.getWriter().write(respJson);}private void save(Message message) throws SQLException {// 通过这个方法把 message 插入到数据库中// 1. 建立连接Connection connection = dataSource.getConnection();// 2. 构造 SQLString sql = "insert into message values(?, ?, ?)";PreparedStatement statement = connection.prepareStatement(sql);statement.setString(1, message.from);statement.setString(2, message.to);statement.setString(3, message.message);// 3. 执行 SQLstatement.executeUpdate();// 4. 回收资源statement.close();connection.close();}private List<Message> load() throws SQLException {// 通过这个方法从数据库读取到 message.// 1. 建立连接Connection connection = dataSource.getConnection();// 2. 构造 SQLString sql = "select * from message";PreparedStatement statement = connection.prepareStatement(sql);// 3. 执行 sqlResultSet resultSet = statement.executeQuery();// 4. 遍历结果集合List<Message> messageList = new ArrayList<>();while (resultSet.next()) {Message message = new Message();message.from = resultSet.getString("from");message.to = resultSet.getString("to");message.message = resultSet.getString("message");messageList.add(message);}// 5. 回收资源resultSet.close();statement.close();connection.close();// 6. 返回 messageListreturn messageList;}
}

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


到此一个简单的,依靠 servlet 的web 页面到此结束了~
下次再见~

这篇关于Java EE Servlet之服务器版表白墙的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/555893

相关文章

Spring Cloud Hystrix原理与注意事项小结

《SpringCloudHystrix原理与注意事项小结》本文介绍了Hystrix的基本概念、工作原理以及其在实际开发中的应用方式,通过对Hystrix的深入学习,开发者可以在分布式系统中实现精细... 目录一、Spring Cloud Hystrix概述和设计目标(一)Spring Cloud Hystr

Spring Boot整合消息队列RabbitMQ的实现示例

《SpringBoot整合消息队列RabbitMQ的实现示例》本文主要介绍了SpringBoot整合消息队列RabbitMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装Spring

springMVC返回Http响应的实现

《springMVC返回Http响应的实现》本文主要介绍了在SpringBoot中使用@Controller、@ResponseBody和@RestController注解进行HTTP响应返回的方法,... 目录一、返回页面二、@Controller和@ResponseBody与RestController

JAVA集成本地部署的DeepSeek的图文教程

《JAVA集成本地部署的DeepSeek的图文教程》本文主要介绍了JAVA集成本地部署的DeepSeek的图文教程,包含配置环境变量及下载DeepSeek-R1模型并启动,具有一定的参考价值,感兴趣的... 目录一、下载部署DeepSeek1.下载ollama2.下载DeepSeek-R1模型并启动 二、J

springboot rocketmq配置生产者和消息者的步骤

《springbootrocketmq配置生产者和消息者的步骤》本文介绍了如何在SpringBoot中集成RocketMQ,包括添加依赖、配置application.yml、创建生产者和消费者,并展... 目录1. 添加依赖2. 配置application.yml3. 创建生产者4. 创建消费者5. 使用在

Spring Retry 实现乐观锁重试实践记录

《SpringRetry实现乐观锁重试实践记录》本文介绍了在秒杀商品SKU表中使用乐观锁和MybatisPlus配置乐观锁的方法,并分析了测试环境和生产环境的隔离级别对乐观锁的影响,通过简单验证,... 目录一、场景分析 二、简单验证 2.1、可重复读 2.2、读已提交 三、最佳实践 3.1、配置重试模板

Spring中@Lazy注解的使用技巧与实例解析

《Spring中@Lazy注解的使用技巧与实例解析》@Lazy注解在Spring框架中用于延迟Bean的初始化,优化应用启动性能,它不仅适用于@Bean和@Component,还可以用于注入点,通过将... 目录一、@Lazy注解的作用(一)延迟Bean的初始化(二)与@Autowired结合使用二、实例解

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J

Java中有什么工具可以进行代码反编译详解

《Java中有什么工具可以进行代码反编译详解》:本文主要介绍Java中有什么工具可以进行代码反编译的相关资,料,包括JD-GUI、CFR、Procyon、Fernflower、Javap、Byte... 目录1.JD-GUI2.CFR3.Procyon Decompiler4.Fernflower5.Jav

Spring Boot 中正确地在异步线程中使用 HttpServletRequest的方法

《SpringBoot中正确地在异步线程中使用HttpServletRequest的方法》文章讨论了在SpringBoot中如何在异步线程中正确使用HttpServletRequest的问题,... 目录前言一、问题的来源:为什么异步线程中无法访问 HttpServletRequest?1. 请求上下文与线