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

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis