《蒼穹外賣》項目日記_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://www.pswp.cn/web/96485.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/96485.shtml
英文地址,請注明出處:http://en.pswp.cn/web/96485.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

人工智能學習:Transformer結構中的編碼器層(Encoder Layer)

Transformer結構中的編碼器層(Encoder Layer) 一、編碼器層介紹 概念 編碼器層(Encoder Layer)是Transformer編碼器的基本構建單元,它重復堆疊形成整個編碼器,負責逐步提取輸入序列的特征。每個編碼器層由兩個核心子層組成: 多頭自注意力機制(Multi-Head Self-Attentio…

2018年下半年 系統架構設計師 綜合知識

1.在磁盤調度管理中&#xff0c;應先進行移臂調度&#xff0c;再進行旋轉調度。假設磁盤移動臂位于21 號柱面上&#xff0c;進程的請求序列如下表所示。如果采用最短移臂調度算法&#xff0c;那么系統的響應 序列應為(D )。A.?②⑧③④⑤①⑦⑥⑨ …

數據庫的連接_qt

數據庫的連接形式可以通過cmd查看 1.獲取 UI 輸入的連接參數 // 獲取主機名&#xff08;如"localhost"或IP地址&#xff09; QString hostStr hostEdit->text(); // 從hostEdit控件獲取文本 QByteArray hostBa hostStr.toUtf8(); // 轉換為UTF-8編碼的字節數…

HTML 設計與使用入門

HTML 設計與使用入門 一、完整示例&#xff08;基礎頁面模板&#xff09;這是一個結構清晰、可直接拷貝運行的最小 HTML 模板&#xff1a;<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"utf-8"><meta name"vie…

Gradio全解11——Streaming:流式傳輸的視頻應用(2)——Twilio:網絡服務提供商

Gradio全解11——Streaming&#xff1a;流式傳輸的視頻應用&#xff08;2&#xff09;——Twilio&#xff1a;網絡服務提供商11.2 Twilio&#xff1a;網絡服務提供商11.2.1 Twillo穿透服務與TURN服務器1. 什么是STUN、TURN和ICE&#xff1f;2. Twilio介紹及網絡穿透服務3. Twil…

【更新至2024年】2009-2024年各地級市金融科技水平數據

【更新至2024年】2009-2024年各地級市金融科技水平數據 1、時間&#xff1a;2009-2024年 2、來源&#xff1a;天眼查 3、指標&#xff1a;年份、省份、地級市、地級市代碼、當年新注冊金融科技公司數量、累計注冊金融科技公司數量、金融科技水平 4、范圍&#xff1a;地級市…

一般軟件加載顯示圖片的流程

目錄 1、一般圖片瀏覽軟件的流程&#xff08;Qt 或類似框架&#xff09;&#xff1a; 1?? 讀取原始數據 2?? 解析圖片格式 3?? 存儲到內部可用的繪制對象 4?? 顯示到界面 ? 總結 2、那什么叫“QPixmap 在 Qt 里就是“顯示專用的像素緩存”&#xff0c;不是原始…

【論文閱讀】REFRAG:一個提升RAG解碼效率的新思路

引言 看到一則報道[1]&#xff0c;重組后的Meta實驗室在9月1號發布了一篇關于提升RAG解碼效率的論文&#xff0c;提出的思路有點啟發作用&#xff0c;于是把原文下載下來仔細看下。 論文標題&#xff1a;REFRAG: Rethinking RAG based Decoding 論文地址&#xff1a;https://ar…

QT M/V架構開發實戰:QFileSystemModel介紹

目錄[TOC](目錄)前言一、QFileSystemModel初步介紹二、基本功能1.創建2.基本屬性與方法三、示例&#xff08;簡單的文件瀏覽器&#xff09;四、性能注意事項前言 本文主要介紹的是使用代碼生成的情況下對控件的介紹&#xff0c;包括擁有的功能及能修改的樣式&#xff0c;也會說…

視頻生成迎來效率革命!字節提出視頻生成稀疏注意力機制,計算量降20倍,速度升17.79倍!

論文鏈接&#xff1a;https://arxiv.org/pdf/2509.01085亮點直擊BSA——一種可訓練的雙向動態稀疏注意力框架&#xff0c;該框架首次在視頻擴散訓練中對全注意力機制中的查詢&#xff08;Query&#xff09;及鍵值對&#xff08;Key-Value&#xff09;進行正交稀疏化處理以加速訓…

STM32HAL庫_cubeMX

ADC簡介STM32f103的是12位逼近型ADC代碼連續非掃描模式&#xff08;1個通道&#xff09;1&#xff1a;校準ADC&#xff08;這個可要可不要&#xff09;2&#xff1a;ADC初始化3&#xff1a;配置ADC通道&#xff08;這個函數只有一個通道時就是可要可不要&#xff09;4&#xff…

【Qt】清空QDateTimeEdit

代碼 ui->startDate->setSpecialValueText(" "); //這里是空格 ui->startDate->setMinimumDate(QDate(2024, 1, 1)); ui->startDate->setDate(QDate::fromString("2024-01-01", "yyyy-MM-dd"));原理 設置特殊值顯示文本&#…

LiTS 2017 datasets

下載記錄 論文地址&#xff1a;https://doi.org/10.1016/j.media.2022.102680 官方下載鏈接&#xff1a;https://competitions.codalab.org/competitions/17094 進入鏈接后&#xff0c;需要先注冊才能拿到下載點擊Train data下面的Mirro1&#xff0c;在google云盤會看到Trai…

kafka3.8集群搭建

kafka集群需要三臺機器搭建&#xff0c;并使用內置zookeeperIP10.0.0.110.0.0.210.0.0.3安裝jdk # ubuntu sudo apt install -y openjdk-8-jdk-headless # centos sudo yum install -y java-1.8.0-openjdk下載kafka wget https://archive.apache.org/dist/kafka/3.8.1/kafka_2…

從15kHz 到20MHz:為什么LTE帶寬不能被子載波間隔整除?

從 15 kHz 到 20 MHz&#xff1a;為什么 LTE 帶寬不能被子載波間隔整除&#xff1f; 1. 引言 在 LTE 系統中&#xff0c;子載波間隔被固定為 15 kHz&#xff0c;而系統帶寬卻被設計為 1.4、3、5、10、15、20 MHz 六個檔位。乍一看&#xff0c;這些帶寬似乎無法被 15 kHz 整除&a…

html css js網頁制作成品——HTML+CSS娃娃店網頁設計(4頁)附源碼

目錄 一、?????網站題目 二、??網站描述 三、??網站介紹 四、??網站效果 五、?? 代碼實現 ??HTML

【計算機網絡 | 第15篇】動態主機配置協議

文章目錄為何需要DHCP&#xff1f;手動配置的痛點&#x1f914;DHCP的基本工作模式&#x1f95d;DHCP的核心功能&#xff1a;IP地址的動態管理&#x1f95d;租用期的特點租用期的管理機制DHCP四步工作流程&#xff1a;從“發現”到“綁定”&#x1f426;?&#x1f525;中繼代理…

嵌入式系統內存分段核心內容詳解

一、嵌入式內存分段整體規則&#xff08;按地址從低到高&#xff09;嵌入式系統內存按 “功能 屬性” 劃分為 6 個核心段&#xff0c;地址從低到高依次分布&#xff0c;各段職責與存儲對象明確&#xff0c;具體規則如下表&#xff1a;地址范圍段類型&#xff08;Segment&#…

開發避坑指南(45):Java Stream 求兩個List的元素交集

需求 java 中如何用stream求兩個List元素的交集&#xff1f; 代碼實現 直接上代碼 public class ListTest {public static void main(String[] args) {List<Integer> list1 new ArrayList<>();list1.add(1);list1.add(2);list1.add(3);List<Integer> list2 …

gitlab流水線與k8s集群的聯通

gitlab流水線與k8s集群的連接&#xff0c;首先是通過gitlab-ci.yml文件中的命令&#xff0c;通過runner執行器實例運行對應的kubectl命令實現的。 那么runner執行器實例執行器如何執行kubectl命令&#xff0c;執行環境的配置&#xff0c;kubectl命令如何與k8s集群互認&#xff…