当前位置: 首页 > news >正文

《苍穹外卖》项目日记_Day9

前言:

上午就把今天任务完成了,就继续往后学了一些知识,晚上写下笔记总结一下。

今日完成任务:

  • 调用百度地图开放平台,优化用户下单业务
  • 学习SpringTask,定时处理超时、派送中订单
  • 学习WebSocket,完成来单提醒、催单业务
  • 完成 数据统计四个接口
  • 学习Apache POI 在java中操作excel

今日收获:

1.学习了SpringTask这个轻量级框架,来解决一些定时处理的问题。

Spring Taskspring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。主要的作用就是定时的去执行某段Java代码。

像这种定时的去执行某个任务,在生活中是比较常见的,例如:闹钟、信用卡每月还款提醒、入职纪念日为用户发送通知等。这些操作不可能有我们开发者/管理端,每次去点击提醒,所有需要根据业务逻辑,定时的去执行某一段代码。所有说,只要是需要定时处理的场景都可以使用Spring Task,Java中还存在其他任务调度工具,如下方案:

方案复杂度分布式支持持久化管理界面适用场景
Spring Task简单否(单机)单机简单定时任务
Quartz中等是(需配置)是(可选)无(需自研)复杂调度、高可靠
ScheduledExecutorService简单并行定时任务
XXL-JOB / Elastic-Job中等分布式系统、集中管理
消息队列延迟复杂依赖MQ高可靠、解耦场景

如何去使用SpringTask任务调度工具定时的执行某段Java代码?

这个框架小到已经包含在SpringBoot的起步依赖中了,所以我们无需引入依赖。首先我们需要在启动类上加上@EnableScheduled注解。然后创建一个包,然后去定义一个task类即可,如下图:

在这里插入图片描述

注意这里的@Scheduled就可,在里面我们可以通过cron表达式去设置该任务自动执行的时间。每次到这个时间就会去执行如下方法。这里的cron表达式我们无需记忆,需要的时候可以通过在线工具去获取到https://cron.qqe2.com/。

这里在该项目中,具体的使用:

  • 超时未支付订单

每隔1min,去数据库中查询超时的订单(15分钟内未支付,订单状态为未支付的订单),然后通过循环将所有超时订单都保存在列表中,通过循环对所有订单状态进行更新。

这里做法存在一些问题

1)订单量大的时候 每隔一分钟就去查询数据库中的数所有的订单数据,对数据库的压力大。(这里可以用redis来解决吧,每隔一分钟去redis缓存中查询,只有查到超时订单的时候,才会对数据库进行更新操作,从而减小数据库的压力)

2)如果订单还要1s 倒计时 未支付 这个时候 订单并没有自动处理成已取消 导致到了时间 但是用户仍然付款了

在这里插入图片描述

  • 派送中订单

每天凌晨去数据库中查找派送中的订单(订单状态为派送中的订单),道理同上,对所有订单状态进行更新。

在这里插入图片描述

2.学习WebSocket,来完成来来单提醒、催单业务

WebSocket 是基于 TCP 的一种新的网络协议。它实现了浏览器与服务器全双工通信-浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输

HTTP协议和WebSocket协议对比:

  • HTTP协议是短连接,WebSocket是长连接
  • HTTP请求是单向的,基于请求和响应模式
  • WebSocket支持双向通信,客户端 <—>服务端
  • 二者底层都是TCP连接

在这里插入图片描述

使用WebSocket

使用前需导入WebSocket的依赖,然后创建Websocket包,创建一个WebSocket服务端组件WebSocketServer,用于和客户端通信,这个服务端组件WebSocketServer写法比较固定,可以参考下面的代码:

package com.sky.websocket;import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;/*** WebSocket服务*/
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {//存放会话对象private static Map<String, Session> sessionMap = new HashMap();/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("sid") String sid) {System.out.println("客户端:" + sid + "建立连接");sessionMap.put(sid, session);}/*** 收到客户端消息后调用的方法* @param message 客户端发送过来的消息*/@OnMessagepublic void onMessage(String message, @PathParam("sid") String sid) {System.out.println("收到来自客户端:" + sid + "的信息:" + message);}/*** 连接关闭调用的方法* @param sid*/@OnClosepublic void onClose(@PathParam("sid") String sid) {System.out.println("连接断开:" + sid);sessionMap.remove(sid);}/*** 群发* @param message*/public void sendToAllClient(String message) {Collection<Session> sessions = sessionMap.values();for (Session session : sessions) {try {//服务器向客户端发送消息session.getBasicRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}}

后我们需要在配置类中创建配置类WebSocketConfiguration.

package com.sky.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;/*** WebSocket配置类,用于注册WebSocket的Bean*/
@Configuration
public class WebSocketConfiguration {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}}

下面解释为什么需要书写这个配置类:

1)WebSocketServer 的作用
WebSocketServer 是一个具体的 WebSocket服务端实现,用于处理客户端连接、消息接收、连接关闭等逻辑。
它通过注解(如 @ServerEndpoint、@OnOpen、@OnMessage 等)定义了 WebSocket 的行为,包括:建立连接时的逻辑 (@OnOpen)。接收客户端消息时的处理逻辑(@OnMessage)。连接关闭时的清理逻辑 (@OnClose)。提供群发消息的功能。

2)WebSocketConfiguration 的作用
WebSocketConfiguration 是一个配置类,主要目的是注册 WebSocket 相关的 Bean
其核心是通过 ServerEndpointExporter 来扫描和注册所有使用 @ServerEndpoint 注解的类(例如 WebSocketServer)。如果没有 ServerEndpointExporter,Spring 容器不会自动识别和管理 @ServerEndpoint 注解的类,导致 WebSocket 功能无法正常工作。

3)为什么需要两个类?
职责分离:WebSocketServer 负责具体的业务逻辑,而 WebSocketConfiguration 负责基础配置。这种设计符合单一职责原则,使代码更清晰、易于维护。
Spring 管理依赖:@ServerEndpoint 注解本身是由 Java EE 提供的,Spring 并不直接支持它。通过 ServerEndpointExporter,Spring 才能将 @ServerEndpoint 注解的类纳入其管理范围。
灵活性:如果未来需要扩展 WebSocket 功能(例如添加拦截器或自定义配置),可以在 WebSocketConfiguration 中进行扩展,而无需修改 WebSocketServer。

简而言之:Spring并不识别带有@ServerEndpoint 注解的WebSocketServer类,该注解由javaEE提供的,Spring并不支持。因此我们需要通过注册配置类ServerEndpointExporter,该配置类会扫描和注册使用@ServerEndpoint注解的类,加入到IOC容器中,使得WebSocket可以正常工作

Nginx的反向代理

具体可以看Day1天的笔记

3.Apache POI

Apache POl是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用 POl在 Java 程序中对Miscrosoft Office各种文件进行读写操作。一般情况下,POI都是用于操作 Excel 文件

在这里插入图片描述

简而言之:Apache POI就是定义了一系列API供我们在java程序中操作excel。除了Apache POI 还有easyExcel等开源工具。

基本思路:1)设计excel模板 2)查询数据库 3)填充数据到模板 4)通过输出流 下载到浏览器

下面是Apache POI操作java的两个Demo文件 供我们熟悉POI操作的相关API

    /*** 使用POI 写入excel文件内容* @throws IOException*/@Testpublic void testWrite() throws IOException {//创建excel文件XSSFWorkbook excel = new XSSFWorkbook();//创建sheetXSSFSheet sheet = excel.createSheet("info");//创建行 这里起始行为0 类似数组XSSFRow row = sheet.createRow(1);//创建单元格 并写入值row.createCell(1).setCellValue("姓名");row.createCell(2).setCellValue("地址");row = sheet.createRow(2);row.createCell(1).setCellValue("张三");row.createCell(2).setCellValue("北京");row = sheet.createRow(3);row.createCell(1).setCellValue("李四");row.createCell(2).setCellValue("青岛");//写入文件FileOutputStream fileOutputStream = new FileOutputStream("D:\\info.xlsx");excel.write(fileOutputStream);}
 /*** 使用POI 读取文件内容**/@Testpublic void testRead() throws IOException {//打开excelXSSFWorkbook excel = new XSSFWorkbook(new FileInputStream(new File("D:\\info.xlsx")));//读取sheet页XSSFSheet sheet = excel.getSheet("info");//获取最后一行下标int lastRowNumber = sheet.getLastRowNum();for (int i = 1; i <= lastRowNumber; i++) {XSSFRow row = sheet.getRow(i);String value1 = row.getCell(1).getStringCellValue();String value2 = row.getCell(2).getStringCellValue();System.out.println(value1 + " " + value2);}}

杂项知识点:

JDK8时间API

JDK 8 引入了全新的时间 API:java.time,它是基于 ThreeTen 项目实现的,更加清晰、易用、不可变、线程安全。

主要类如下:

类名用途
LocalDate只包含日期,无时区(如:2025-09-04)
LocalTime只包含时间,无时区(如:10:30:45)
LocalDateTime日期 + 时间,无时区(如:2025-09-04T10:30:45)
ZonedDateTime带有时区的日期时间(如:2025-09-04T10:30:45+08:00[Asia/Shanghai])
Instant时间戳,表示从 1970-01-01T00:00:00Z 起的秒或纳秒数
Duration表示两个时间点之间的时间量(以秒或纳秒为单位)
Period表示两个日期之间的年月日差异(以年、月、日为单位)

获取每天的日期列表

List<LocalDate> dateList = new ArrayList<>() ;       
//1.日期列表
dateList.add(begin);
while(!begin.equals(end)){//未达到结束时间begin = begin.plusDays(1);dateList.add(begin);
}
//列表转字符串
StringUtils.join(dateList,",");

总结:

​ 今天学了挺多小的知识点,然后自己还把数据统计的那几个接口完成了,感觉那几个接口都好像,一些重复性的逻辑,然后呢把这个项目整体都完成了,后边的计划就是明天写一篇项目总结,然后休息两天,看一下后边的计划。

您的一个小小点赞,对我便是莫大的鼓励。感谢支持!


文章转载自:

http://V1qae39n.zdxss.cn
http://Kidi1jwi.zdxss.cn
http://46uo23Sj.zdxss.cn
http://EMuZsaar.zdxss.cn
http://3RPciUM8.zdxss.cn
http://cxOHSBvZ.zdxss.cn
http://cWoacjQl.zdxss.cn
http://9iEU16K1.zdxss.cn
http://H4tOMiq2.zdxss.cn
http://5kWz0ZVf.zdxss.cn
http://YRXlgiZa.zdxss.cn
http://6p4hfv9r.zdxss.cn
http://JE3m2ROX.zdxss.cn
http://zopdf6Fn.zdxss.cn
http://bsEN8VXp.zdxss.cn
http://BtkAZPkM.zdxss.cn
http://JIN2C9Ue.zdxss.cn
http://kjQwZvYL.zdxss.cn
http://qKZqHNZC.zdxss.cn
http://bYlqpEwY.zdxss.cn
http://kgQaGIzX.zdxss.cn
http://PxQljszm.zdxss.cn
http://lmzrWLWT.zdxss.cn
http://DQ46W3h1.zdxss.cn
http://5nrYKQHE.zdxss.cn
http://oLBLUWYs.zdxss.cn
http://SngBv7kx.zdxss.cn
http://rIaAsujj.zdxss.cn
http://zNCh05Jr.zdxss.cn
http://QrAA0HGi.zdxss.cn
http://www.dtcms.com/a/381329.html

相关文章:

  • 文件检查与拷贝-简化版
  • 电容式原理检测微小位移的技术方案以及芯片方案
  • 嵌入式系统内存分段核心内容详解
  • AI生成内容检测的综合方法论与技术路径
  • 材料基因组计划(MGI)入门:高通量计算与数据管理最佳实践
  • 系统地总结一下Python中关于“遍历”的知识点
  • Android面试指南(九)
  • Halcon编程指南:符号与元组操作详解
  • 嵌入式第五十二天(GIC,协处理器,异常向量表)
  • 嵌入式学习day48-硬件-imx6ul-key、中断
  • 查找算法和递推算法
  • Webman 微服务集成 RustFS 分布式对象存储
  • 基于51单片机的太阳能锂电池充电路灯
  • 【人工智能通识专栏】第十三讲:图像处理
  • 滚动分页查询-通俗解释
  • 电缆工程量计算-批量测量更轻松
  • UDS NRC速查
  • L2-【英音】地道语音语调--语调
  • 13.渗透-.Linux基础命令(五)-用户管理(修改用户密码)
  • 解决串口数据乱序问题
  • 智能化集成系统(IBMS):构建智慧建筑 “中枢大脑” 的全方案
  • 基于游标(Cursor)的方式来实现滚动分页
  • 30.线程的互斥与同步(四)
  • 《没有架构图?用 netstat、ss、tcpdump 还原服务连接与数据流向》
  • 仓颉语言编程入门:第一个 Windows 下的仓颉应用程序
  • 台达A2E
  • 【操作系统核心考点】进程调度算法全面总结:高频题型与易错点解析
  • ethercat在线调试工具
  • python base core partment-day07-异常、模块、包(对零基础小白友好)
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘vaex’问题