Easy云盤總結篇-登錄注冊

**說在前面:該項目是跟著B站一位大佬寫的,不分享源碼,支持項目付費 **

獲取圖形驗證碼

在這里插入圖片描述
可以看到這里有2兩種圖形驗證碼,分為:
type=0:如上圖下面那個,是完成操作后要進行注冊的驗證碼
type=1: 如上圖上面那個,是要發送郵箱之前的圖形驗證碼。
在這里插入圖片描述
這里在交互時,設置了session值,存放了兩種圖形驗證碼,便于后面進行用戶輸入情況和session值比對。
那什么是session呢?
(1)Session用于記錄用戶的狀態。Session指的是一段時間內,單個客戶端與Web服務器的一連串相關的交互過程

(2)在一個Session中,客戶可能會多次請求訪問同一個資源,也有可能請求訪問各種不同的服務器資源。

(3)Session是由服務器端創建的一個對象

可能涉及到的session操作

  • session.setAttribute(key,value)

    類似hashmap,存放鍵值。

  • session.getAttribute(key)

    根據key獲取值,獲得值的類型為object,要根據情況進行強轉

  • session.removeAttribute(key)

    刪除該key和對應的值,但session這個對象還在

  • session.invalidate()

    銷毀了session對象

那如果是多服務器上部署這個項目,涉及多個session:

當系統部署到多臺服務器時,由于每個服務器都有自己獨立的內存空間,默認情況下 HttpSession 是無法在不同服務器之間共享的。這會導致用戶在不同服務器上的請求無法正確識別其會話狀態,例如用戶在一臺服務器上登錄成功,但下一次請求被分配到另一臺服務器時,該服務器無法獲取到用戶的登錄狀態。為了解決這個問題:

使用分布式緩存(如 Redis)是一種比較常用的解決方案。它將 Session 數據存儲在 Redis 中,而不是存儲在服務器的內存中。這樣,所有服務器都可以通過 Redis 來獲取和更新 Session 數據,從而實現了 Session 的共享。這種方案具有較好的擴展性和性能,而且可以避免會話復制帶來的網絡開銷。

這里給出圖形驗證碼是如何生成的:

public class CreateImageCode {// 圖片的寬度。private int width = 160;// 圖片的高度。private int height = 40;// 驗證碼字符個數private int codeCount = 4;// 驗證碼干擾線數private int lineCount = 20;// 驗證碼private String code = null;// 驗證碼圖片Bufferprivate BufferedImage buffImg = null;Random random = new Random();public CreateImageCode() {creatImage();}public CreateImageCode(int width, int height) {this.width = width;this.height = height;creatImage();}public CreateImageCode(int width, int height, int codeCount) {this.width = width;this.height = height;this.codeCount = codeCount;creatImage();}public CreateImageCode(int width, int height, int codeCount, int lineCount) {this.width = width;this.height = height;this.codeCount = codeCount;this.lineCount = lineCount;creatImage();}// 生成圖片private void creatImage() {int fontWidth = width / codeCount;// 字體的寬度int fontHeight = height - 5;// 字體的高度int codeY = height - 8;// 圖像bufferbuffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g = buffImg.getGraphics();//Graphics2D g = buffImg.createGraphics();// 設置背景色g.setColor(getRandColor(200, 250));g.fillRect(0, 0, width, height);// 設置字體//Font font1 = getFont(fontHeight);Font font = new Font("Fixedsys", Font.BOLD, fontHeight);g.setFont(font);// 設置干擾線for (int i = 0; i < lineCount; i++) {int xs = random.nextInt(width);int ys = random.nextInt(height);int xe = xs + random.nextInt(width);int ye = ys + random.nextInt(height);g.setColor(getRandColor(1, 255));g.drawLine(xs, ys, xe, ye);}// 添加噪點float yawpRate = 0.01f;// 噪聲率int area = (int) (yawpRate * width * height);for (int i = 0; i < area; i++) {int x = random.nextInt(width);int y = random.nextInt(height);buffImg.setRGB(x, y, random.nextInt(255));}String str1 = randomStr(codeCount);// 得到隨機字符this.code = str1;for (int i = 0; i < codeCount; i++) {String strRand = str1.substring(i, i + 1);g.setColor(getRandColor(1, 255));// g.drawString(a,x,y);// a為要畫出來的東西,x和y表示要畫的東西最左側字符的基線位于此圖形上下文坐標系的 (x, y) 位置處g.drawString(strRand, i * fontWidth + 3, codeY);}}// 得到隨機字符private String randomStr(int n) {String str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";String str2 = "";int len = str1.length() - 1;double r;for (int i = 0; i < n; i++) {r = (Math.random()) * len;str2 = str2 + str1.charAt((int) r);}return str2;}// 得到隨機顏色private Color getRandColor(int fc, int bc) {// 給定范圍獲得隨機顏色if (fc > 255) fc = 255;if (bc > 255) bc = 255;int r = fc + random.nextInt(bc - fc);int g = fc + random.nextInt(bc - fc);int b = fc + random.nextInt(bc - fc);return new Color(r, g, b);}/*** 產生隨機字體*/private Font getFont(int size) {Random random = new Random();Font font[] = new Font[5];font[0] = new Font("Ravie", Font.PLAIN, size);font[1] = new Font("Antique Olive Compact", Font.PLAIN, size);font[2] = new Font("Fixedsys", Font.PLAIN, size);font[3] = new Font("Wide Latin", Font.PLAIN, size);font[4] = new Font("Gill Sans Ultra Bold", Font.PLAIN, size);return font[random.nextInt(5)];}// 扭曲方法private void shear(Graphics g, int w1, int h1, Color color) {shearX(g, w1, h1, color);shearY(g, w1, h1, color);}private void shearX(Graphics g, int w1, int h1, Color color) {int period = random.nextInt(2);boolean borderGap = true;int frames = 1;int phase = random.nextInt(2);for (int i = 0; i < h1; i++) {double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);g.copyArea(0, i, w1, 1, (int) d, 0);if (borderGap) {g.setColor(color);g.drawLine((int) d, i, 0, i);g.drawLine((int) d + w1, i, w1, i);}}}private void shearY(Graphics g, int w1, int h1, Color color) {int period = random.nextInt(40) + 10; // 50;boolean borderGap = true;int frames = 20;int phase = 7;for (int i = 0; i < w1; i++) {double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames);g.copyArea(i, 0, 1, h1, 0, (int) d);if (borderGap) {g.setColor(color);g.drawLine(i, (int) d, i, 0);g.drawLine(i, (int) d + h1, i, h1);}}}public void write(OutputStream sos) throws IOException {ImageIO.write(buffImg, "png", sos);sos.close();}public BufferedImage getBuffImg() {return buffImg;}public String getCode() {return code.toLowerCase();}
}

發郵箱前驗證碼

在這里插入圖片描述
這段的實現邏輯:

根據傳過來的參數,其中type 0:注冊郵箱時 1:重置密碼時(后續)

先進行發郵箱前的圖形驗證碼校對,對應后,執行發送郵箱操作。

最后,清空一下session存的當前驗證碼。如果驗證碼在使用后不被清除,那么惡意用戶可能會獲取到該驗證碼,并在后續的請求中重復使用,從而繞過驗證碼的驗證機制,對系統的安全性造成威脅。

在這里插入圖片描述
這段邏輯就是發送驗證碼前檢驗該賬號是否已經注冊

發送郵箱后,如果重復發送發送郵箱的話,需要將之前的郵箱驗證碼設置為1:用過了
在這里插入圖片描述

然后是發送郵箱的實現:
在這里插入圖片描述

AOP切面實現參數校驗

在前端傳過來的各種參數,我們需要進行非空校驗,最笨的方法就是if else判斷,這樣耗時耗力,很不適用,為了減少冗雜性判斷為空代碼,通過注解作用在參數上,實現切面類判斷。
首先,創建攔截器:
第一個是對參數進行校驗,@GlobalInterceptor 注解的主要目的是標記需要進行特定攔截處理的方法,其中 checkParams = true 表示需要對方法的參數進行校驗。
在這里插入圖片描述
而這個,是對某參數進行具體的校驗:
在這里插入圖片描述
然后就是切面設計:AOP 可以在方法執行前攔截方法調用,并對方法的參數進行校驗。
在這里插入圖片描述

注冊

在這里插入圖片描述
這段邏輯
首先進行注冊前的圖形驗證碼校對
然后執行注冊操作
最后再清空session存的當前圖形驗證碼。

service層實現:
在這里插入圖片描述
再次檢查是否郵箱已經注冊,比對昵稱唯一(項目要求唯一)
然后根據表中之前存的郵箱和郵箱驗證碼,跟現在填的進行比對 ,校驗通過后,插入用戶信息,其中用戶網盤空間分配:已用空間0,總空間初始分配5MB.
其中校驗對應:在這里插入圖片描述
分兩種情況
1:郵箱和郵箱驗證碼不能對應起來,視為錯誤
2:郵箱驗證碼之前設置過15分鐘內有效。一旦超時,視為無效,再次更改表,將這個郵箱驗證碼設置為1:已用過

System.currentTimeMillis():用來獲取當前的總毫秒數

getTime():返回毫秒數

登錄

在這里插入圖片描述
這段的邏輯
同樣檢查圖形驗證碼
然后設置了一個dto(含id昵稱頭像)來接收登錄信息,設置session當前登錄信息, 并將這個dto返回給VO
serviceImpl:
在這里插入圖片描述
這段邏輯
通過郵箱比對是否該賬號注冊了或者密碼對不上。不能分情況if,不讓用戶知道具體是哪個錯了。
然后就算是它登錄了,就要更新其登錄時間,給dto的屬性賦值
另外還查看是否是超級管理員,如果是,則dto的isAdmin設為true。
成功登陸后,給用戶分配網盤空間。注冊時是給user標注空間分配信息,現在設置的是方便在redis中存儲

忘記密碼

在這里插入圖片描述
和注冊邏輯相似,重置密碼,主要就是更新一下password。而發送郵箱等業務是已經完成了的,才把emailCode傳過來了。
在這里插入圖片描述

修改密碼

這個和忘記密碼重置有區別,忘記密碼是沒登錄進去時重置,這個是登進去后在個人設置里修改。
controller
在這里插入圖片描述
這段邏輯
通過繼承AbaseController類里的方法getUserInfoFromSession,通過session找到其SESSION_KEY對應的dto返回,再通過dto獲取當前用戶id,進行密碼修改。

獲取默認頭像

在這里插入圖片描述

mkdir()和mkdirs()
創建文件夾。
mkdir方法是用于創建最后一個/后面的文件夾,最后一個/前面的文件夾必須都存在。
mkdirs方法是無論父文件夾是否存在都會創建。

這段邏輯

先在配置文件中定義了項目根目錄文件夾,隨后定義文件file/和用于存放頭像的avatar/文件夾,如果沒有這個文件夾,就創建。總的合起來組成一個完整的頭像路徑字符串
項目根目錄/file/avatar/user123.jpg
如果還是沒有這個文件,再看看有沒有設置默認頭像路徑 項目根目錄/file/avatar/default.jpg
然后讀取文件。

上傳頭像

在這里插入圖片描述
這段邏輯
先獲取dto用戶信息,然后就是找到或創建存放頭像的文件夾,將用戶上傳的文件保存到這個文件夾里
因為自定義頭像需要覆蓋原來的qq頭像,所以qq頭像設置為空
然后webUserDto的avatar也被設為null,并更新到session中,這樣下次請求時用戶的最新頭像信息會被重新加載現在自定義好的或者使用默認頭像。

關于MultipartFile

MultipartFile:

public interface MultipartFile extends InputStreamSource {
//getName() 返回參數的名稱
String getName();
//獲取源文件的昵稱
@Nullable
String getOriginalFilename();
//getContentType() 返回文件的內容類型
@Nullable
String getContentType();
//isEmpty() 判斷是否為空,或者上傳的文件是否有內容
boolean isEmpty();
//getSize() 返回文件大小 以字節為單位
long getSize();
//getBytes() 將文件內容轉化成一個byte[] 返回
byte[] getBytes() throws IOException;
//getInputStream() 返回InputStream讀取文件的內容
InputStream getInputStream() throws IOException;default Resource getResource() {return new MultipartFileResource(this);
}
//transferTo是復制file文件到指定位置(比如D盤下的某個位置),不然程序執行完,文件就會消失,程序運行時,臨時存儲在temp這個文件夾中
void transferTo(File var1) throws IOException, IllegalStateException;default void transferTo(Path dest) throws IOException, IllegalStateException {FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest));
}
}

這里前端傳過來文件,我們用MultipartFile avatar 接收

關于getPath()

將抽象路徑名轉換為一個路徑名字符串。所得到的字符串使用默認名稱分隔符來分隔名稱序列中的名稱。

public   static   void  test1() {File file1 = new File(".\\test1.txt");File file2 = new File("D:\\workspace\\test\\test1.txt");System.out.println("-----默認相對路徑:取得路徑不同------");System.out.println(file1.getPath());System.out.println(file1.getAbsolutePath());System.out.println("-----默認絕對路徑:取得路徑相同------");System.out.println(file2.getPath());System.out.println(file2.getAbsolutePath());  
}----- 默認相對路徑:取得路徑不同 ------
.\test1.txt
D:\workspace\test\.\test1.txt
----- 默認絕對路徑:取得路徑相同 ------
D:\workspace\test\test1.txt
D:\workspace\test\test1.txt

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903977.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903977.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903977.shtml

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

相關文章

【前端知識】Vue3狀態組件Pinia詳細介紹

Vue3狀態組件Pinia詳細介紹 關聯知識 Pinia 組件介紹、核心原理及使用方式 Pinia 組件介紹 Pinia 是 Vue.js 的官方狀態管理庫&#xff0c;專為 Vue 3 設計&#xff0c;提供簡潔的 API 和強大的 TypeScript 支持。其核心組件包括&#xff1a; ? Store&#xff1a;狀態存儲容器…

mysql 云服務遠程linux創建數據庫

1. 本地使用已創建好的用戶創建數據庫出現問題 提示access deniey finalshell遠程創建新用戶 :~# mysql -u root -pR***34 > CREATE DATABASE r***e; > CREATE USER r**ue% IDENTIFIED BY Ry****34; > GRANT ALL PRIVILEGES ON ry_vue.* TO r***e%; > FLUSH PRI…

【“星瑞” O6 評測】 — CPU llama.cpp不同優化速度對比

前言 隨著大模型應用場景的不斷拓展&#xff0c;arm cpu 憑借其獨特優勢在大模型推理領域的重要性日益凸顯。它在性能、功耗、架構適配等多方面發揮關鍵作用&#xff0c;推動大模型在不同場景落地 1. Kleidi AI 簡介 Arm Kleidi 成為解決這些挑戰的理想方案&#xff0c;它能…

wireshark抓包也能被篡改?

wireshark本身并不能修改數據包&#xff0c;但是tcprewrite 可以修改數據包&#xff0c;然后通過tcpreplay 進行重放&#xff0c;這個時候wireshark抓的包&#xff0c;就是被篡改后的pcap包了。 ailx10 網絡安全優秀回答者 互聯網行業 安全攻防員 去咨詢 步驟一&#xff1a…

使用PyTorch進行熱狗圖像分類模型微調

本教程將演示如何使用PyTorch框架對預訓練模型進行微調&#xff0c;實現熱狗與非熱狗圖像的分類任務。我們將從數據準備開始&#xff0c;逐步完成數據加載、可視化等關鍵步驟。 1. 環境配置與庫導入 %matplotlib inline import os import torch from torch import nn from d2l…

內容中臺與企業內容管理核心差異剖析

功能定位與架構設計差異 在企業數字化進程中&#xff0c;內容中臺與企業內容管理&#xff08;ECM&#xff09;的核心差異首先體現在功能定位層面。傳統ECM系統以文檔存儲、版本控制及權限管理為核心&#xff0c;主要服務于企業內部知識庫的靜態管理需求&#xff0c;例如通過Ba…

使用PyMongo連接MongoDB的基本操作

MongoDB是由C語言編寫的非關系型數據庫&#xff0c;是一個基于分布式文件存儲的開源數據庫系統&#xff0c;其內容存儲形式類似JSON對象&#xff0c;它的字段值可以包含其他文檔、數組及文檔數組。在這一節中&#xff0c;我們就來回顧Python 3下MongoDB的存儲操作。 常用命令:…

第 12 屆藍橋杯 C++ 青少組中 / 高級組省賽 2021 年真題

一、選擇題 第 1 題 題目&#xff1a;下列符號中哪個在 C 中表示行注釋 ( )。 A. ! B. # C. ] D. // 正確答案&#xff1a;D 答案解析&#xff1a; 在 C 中&#xff0c;//用于單行注釋&#xff08;行注釋&#xff09;&#xff0c;從//開始到行末的內容會被編譯器忽略。選項 A…

【python】【UV】一篇文章學完新一代 Python 環境與包管理器使用指南

&#x1f40d; UV&#xff1a;新一代 Python 環境與包管理器使用指南 一、UV 是什么&#xff1f; UV 是由 Astral 團隊開發的高性能 Python 環境管理器&#xff0c;旨在統一替代 pyenv、pip、venv、pip-tools、pipenv 等工具。 1.1 UV 的主要功能 &#x1f680; 極速包安裝&…

前端性能優化2:結合HTTPS與最佳實踐,全面優化你的網站性能

點亮極速體驗&#xff1a;結合HTTPS與最佳實踐&#xff0c;為你詳解網站性能優化的道與術 在如今這個信息爆炸、用戶耐心極其有限的數字時代&#xff0c;網站的性能早已不是一個可選項&#xff0c;而是關乎生存和發展的核心競爭力。一個遲緩的網站&#xff0c;無異于在數字世界…

JavaWeb:vueaxios

一、簡介 什么是vue? 快速入門 <!-- 3.準備視圖元素 --><div id"app"><!-- 6.數據渲染 --><h1>{{ msg }}</h1></div><script type"module">// 1.引入vueimport { createApp, ref } from https://unpkg.com/vu…

Tauri聯合Vue開發中Vuex與Pinia關系及前景分析

在 TauriVue 的開發場景中&#xff0c;Vuex 和 Pinia 是兩種不同的狀態管理工具&#xff0c;它們的關系和前景可以從以下角度分析&#xff1a; 一、Vuex 與 Pinia 的關系 繼承與發展 Pinia 最初是作為 Vuex 5 的提案設計的&#xff0c;其目標是簡化 Vuex 的復雜性并更好地適配 …

Linux中的時間同步

一、時間同步服務擴展總結 1. 時間同步的重要性 多主機協作需求&#xff1a;在分布式系統、集群、微服務架構中&#xff0c;時間一致性是日志排序、事務順序、數據一致性的基礎。 安全協議依賴&#xff1a;TLS/SSL證書、Kerberos認證等依賴時間有效性&#xff0c;時間偏差可能…

【算法基礎】三指針排序算法 - JAVA

一、基礎概念 1.1 什么是三指針排序 三指針排序是一種特殊的分區排序算法&#xff0c;通過使用三個指針同時操作數組&#xff0c;將元素按照特定規則進行分類和排序。這種算法在處理包含有限種類值的數組時表現出色&#xff0c;最經典的應用是荷蘭國旗問題&#xff08;Dutch …

《操作系統真象還原》第十二章(2)——進一步完善內核

文章目錄 前言可變參數的原理實現系統調用write更新syscall.h更新syscall.c更新syscall-init.c 實現printf編寫stdio.h編寫stdio.c 第一次測試main.cmakefile結果截圖 完善printf修改main.c 結語 前言 上部分鏈接&#xff1a;《操作系統真象還原》第十二章&#xff08;1&#…

ICML2021 | DeiT | 訓練數據高效的圖像 Transformer 與基于注意力的蒸餾

Training data-efficient image transformers & distillation through attention 摘要-Abstract引言-Introduction相關工作-Related Work視覺Transformer&#xff1a;概述-Vision transformer: overview通過注意力機制蒸餾-Distillation through attention實驗-Experiments…

深度學習:AI 機器人時代

在科技飛速發展的當下&#xff0c;AI 機器人時代正以洶涌之勢席卷而來&#xff0c;而深度學習作為其核心驅動力&#xff0c;正重塑著我們生活與工作的方方面面。 從智能工廠的自動化生產&#xff0c;到家庭中貼心服務的智能助手&#xff0c;再到復雜環境下執行特殊任務的專業機…

《告別試錯式開發:TDD的精準質量鍛造術》

深度解鎖TDD&#xff1a;應用開發的創新密鑰 在應用開發的復雜版圖中&#xff0c;如何雕琢出高質量、高可靠性的應用&#xff0c;始終是開發者們不懈探索的核心命題。測試驅動開發&#xff08;TDD&#xff09;&#xff0c;作為一種顛覆性的開發理念與方法&#xff0c;正逐漸成…

應用層自定義協議序列與反序列化

目錄 一、網絡版計算器 二、網絡版本計算器實現 2.1源代碼 2.2測試結果 一、網絡版計算器 應用層定義的協議&#xff1a; 應用層進行網絡通信能否使用如下的協議進行通信呢&#xff1f; 在操作系統內核中是以這種協議進行通信的&#xff0c;但是在應用層禁止以這種協議進行…

Excel-CLI:終端中的輕量級Excel查看器

在數據驅動的今天&#xff0c;Excel 文件處理成為了我們日常工作中不可或缺的一部分。然而&#xff0c;頻繁地在圖形界面與命令行界面之間切換&#xff0c;不僅效率低下&#xff0c;而且容易出錯。現在&#xff0c;有了 Excel-CLI&#xff0c;一款運行在終端中的輕量級Excel查看…