用 SpringBoot 和 SSE 打造动态前端更新的终极指南

你知道什么是开发者的梦魇吗?慢!慢!慢!在一个需要实时数据更新的应用中,如果数据像乌龟一样慢吞吞地爬行,那用户体验就会像坐过山车一样直线下降。所以今天,我们要化身为数据传输的超级英雄,用 SpringBoot 和 SSE(服务器发送事件)打造一个超酷、超快、而且超实时的数据流!

为什么选择 SSE?

在开始我们的冒险之前,先让我们来谈谈为什么要选择 SSE(服务器发送事件)。简单来说,SSE 就像是那个总是知道你需要什么并且在你还没说之前就把它送到你面前的超级服务员。它允许服务器主动将信息“推送”到客户端,而不是等待客户端来“询问”。想象一下,你正在看一场激动人心的球赛直播,而不是每五秒刷新一次页面,SSE 可以帮你实时看到每一个进球。是不是很酷?

创建控制器

好的,现在让我们开始编写一些代码。首先,我们需要创建一个 SpringBoot 控制器。这个控制器就像是魔法世界的大门,让所有神奇的事情开始发生。

@RestController
@RequestMapping("/user")
public class UserController { private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>(); @Autowired
private UserMapper userMapper; @GetMapping(value = "/get",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public SseEmitter getAllUsers(){
SseEmitter emitter = new SseEmitter();
this.emitters.add(emitter); emitter.onCompletion(() -> this.emitters.remove(emitter));
emitter.onError((e) -> this.emitters.remove(emitter));
emitter.onTimeout(() -> this.emitters.remove(emitter)); return emitter;
}
@GetMapping("/add")
public void addUser(){
User user = new User();
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
user.setUsername(formatter.format(now));
user.setPassword(UUID.randomUUID().toString());
userMapper.addUser(user);
sendToClients();
}

我这里做的是从数据库查询数据实时推送到前端,你也可以换成任何你喜欢的方式,在下面的方法中

发送数据

现在,是时候学习一些发送数据的魔法咒语了。每当后端有新的数据更新时,我们就可以调用 sendToClients 方法,让这些数据像小精灵一样飞到每个客户端。

    public void sendToClients() {
List<User> users = userMapper.getUsers();
for (SseEmitter emitter : emitters) {
try {
emitter.send(users);
} catch (IOException e) {
emitter.completeWithError(e);
}
}
}

前端实现

接下来,在前端的世界里,我们需要打开一个魔法视窗来接收这些数据。这个魔法视窗就是 JavaScript 的 EventSource。

<!DOCTYPE html>
<html>
<head>
<title>SSE Example</title>
</head>
<body>
<div id="sse-data"></div> <script>
const sseData = document.getElementById("sse-data"); const eventSource = new EventSource("/user/get"); eventSource.onmessage = (event) => {
sseData.innerHTML = event.data;
}; eventSource.onerror = (error) => {
console.error("SSE Error:", error);
};
</script>
</body>
</html>

整合流程

最后,让我们把这一切魔法整合在一起。启动你的 SpringBoot 应用,打开你的前端页面,你就会看到数据像水一样流畅地在你眼前流淌。不再是冰冷的静态页面,你的应用现在生动、活泼,充满了魔法的力量!

实时数据流无忧:用 SpringBoot 和 SSE 打造动态前端更新的终极指南的更多相关文章

  1. Storm实战:在云上搭建大规模实时数据流处理系统(Storm+Kafka)

    在大数据时代,数据规模变得越来越大.由于数据的增长速度和非结构化的特性,常用的软硬件工具已无法在用户可容忍的时间内对数据进行采集.管理和处理.本文主要介绍如何在阿里云上使用Kafka和Storm搭建大 ...

  2. 打造高效前端工作环境 - tmux

    打造高效前端工作环境 - tmux 前言  现在前端开发可不容易啊,先打开个VIM,然后再打开个lite-server,一不小心写个ES2015还要打开个gulp来做预编译,如果能把这么多个窗口放在一 ...

  3. 【jQuery Demo】jQuery打造动态下滑菜单

    作者:漫凯维奇      来源:[教程]jQuery打造动态下滑菜单 Tip:这只是一个转载,源代码可以在上面的来源博文中下载 此教程将分步讲解如何使用JQuery和CSS打造一个炫酷动感菜单.效果如 ...

  4. spring-boot+quartz的CRUD动态任务管理系统

    版权声明:作者: 小柒 出处: https://blog.52itstyle.com 分享是快乐的,也见证了个人成长历程,文章大多都是工作经验总结以及平时学习积累,基于自身认知不足之处在所难免,也请大 ...

  5. SpringBoot整合MyBatisPlus配置动态数据源

    目录 SpringBoot整合MyBatisPlus配置动态数据源 SpringBoot整合MyBatisPlus配置动态数据源 推文:2018开源中国最受欢迎的中国软件MyBatis-Plus My ...

  6. SpringBoot集成Shiro 实现动态加载权限

    一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...

  7. SpringBoot整合log4j2进行日志配置及防坑指南

    写在前面 最近项目经理要求将原先项目中的日志配置logBack,修改为log4j2,据说是log4j2性能更优于logback,具体快多少,网上有说快10多倍,看来还是很快的,于是新的一波挑战又开始了 ...

  8. SpringBoot 整合Shiro实现动态权限加载更新+Session共享+单点登录

    作者:Sans_ juejin.im/post/5d087d605188256de9779e64 一.说明 Shiro是一个安全框架,项目中主要用它做认证,授权,加密,以及用户的会话管理,虽然Shir ...

  9. Springboot+Mybatis+Pagehelper+Aop动态配置Oracle、Mysql数据源

      本文链接:https://blog.csdn.net/wjy511295494/article/details/78825890 Springboot+Mybatis+Pagehelper+Aop ...

  10. SpringBoot系列教程web篇之过滤器Filter使用指南

    web三大组件之一Filter,可以说是很多小伙伴学习java web时最早接触的知识点了,然而学得早不代表就用得多.基本上,如果不是让你从0到1写一个web应用(或者说即便从0到1写一个web应用) ...

随机推荐

  1. 【Qt6】列表模型——树形列表

    QStandardItemModel 类作为标准模型,主打"类型通用",前一篇水文中,老周还没提到树形结构的列表,本篇咱们就好好探讨一下这货. 还是老办法,咱们先做示例,然后再聊知 ...

  2. Python比较字符串格式类型时间大小

    已知的格式是 06/24/2021 15:47:01.491 时间比较的思路是,把数据转换成时间戳比较: 第一步是把 06/24/2021 15:47:01.491 格式转换称 2021-06-24 ...

  3. 深入理解java和dubbo的SPI机制

    1 SPI简介 1.1 SPI(Service Provider Interface) 本质:将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类.这样可以在运行时,动态为接口替 ...

  4. C#软件架构设计原则

    软件架构设计原则 学习设计原则是学习设计模式的基础.在实际的开发过程中,并不是一定要求所有的代码都遵循设计原则,而是要综合考虑人力.成本.时间.质量,不刻意追求完美,要在适当的场景遵循设计原则.这体现 ...

  5. JS个人总结(2)

    1.null被认为是一个空的对象引用..如果定义的变量准备将来用保存对象,最好将该变量初始化null.即 var x=null;这样只有检查null值就可以知道这个变量是否已经保存了一个对象.. 2. ...

  6. 在不知带头节点地址的情况下删除和插入一个p指针指向的节点总结

    在不知带头节点地址的情况下删除和插入一个p指针指向的节点总结 (p指向的不是第一个,也不是最后一个)A->B->C *p->B 插入(在p结点之前插入q) 解析: 直接往p前插入q, ...

  7. PTA乙级1049

    不能直接两重循环数据是1e5会超时 这样 #include"bitsdc++.h" using namespace std; const int N=1e5+10; double ...

  8. Python 模块:创建、导入和使用

    什么是模块? 将模块视为代码库.模块是一个包含一组函数的文件,您想要在应用程序中包含这些函数. 创建一个模块 要创建一个模块,只需将要包含在其中的代码保存在扩展名为 .py 的文件中: 示例:将以下代 ...

  9. P4156 [WC2016]论战捆竹竿 题解

    题目链接 题意描述 给定一个字符串 \(s\),你初始拥有一个空串 \(t\),每次可以选择这个字符串的一个 Border,去掉它后接在 \(t\) 的后面,操作后 \(s\) 不变,给出一个上限 \ ...

  10. window.onload 触发时机问题

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...