短鏈接學習day2

用戶敏感信息脫敏展示:

@RequestParam 和 @PathVariable的區別

注解是用于從request中接收請求的,兩個都可以接收參數,關鍵點不同的是@RequestParam 是從request里面拿取值,而 @PathVariable 是從一個URI模板里面來填充。

@PathVariable:主要用于接收http://host:port/path/{參數值}數據。

@RequestParam:主要用于接收http://host:port/path?參數名=參數值數據,這里后面也可以不跟參數值。

BeanUtil.toBean()方法

在Hutool工具包中,BeanUtil類的toBean()方法用于將一個對象或Map轉換成指定類型的JavaBean對象。我們先創建了一個數據源對象product,然后,通過調用BeanUtil.toBean()方法,將數據源對象product轉換成目標類型 productVo的JavaBean對象vo。

需要注意的是,轉換過程中,BeanUtil.toBean()方法通過反射機制創建了目標類型的實例,并將數據源對象的屬性值復制到目標對象中。所以,需要保證數據源對象和目標類型的屬性名稱和類型保持一致,否則無法正確轉換屬性值。所以在創建ProductVo時,是繼承于Product的。另外,還需要在項目中引入Hutool的相關依賴才能使用BeanUtil類的方法。

PhoneDesensitizationSerializer:
package com.nageoffer.shortlink.admin.common.serialize;import cn.hutool.core.util.DesensitizedUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;import java.io.IOException;/*** 手機號脫敏反序列化*/
public class PhoneDesensitizationSerializer extends JsonSerializer<String> {@Overridepublic void serialize(String phone, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {String phoneDesensitization = DesensitizedUtil.mobilePhone(phone);jsonGenerator.writeString(phoneDesensitization);}
}

UserRespDTO:

不知道為什么我都加了注解,也有文件,可是脫敏就是不生效,壓根沒走PhoneDesensitizationSerializer。

用戶注冊:

檢查用戶名是否存在:

  • 海量用戶如果說查詢的用戶名存在或不存在,全部請求數據庫,會將數據庫直接打滿。

方法1:將數據庫已有的用戶名全部放到緩存里。

該方案問題:

  • 是否要設置數據的有效期?只能設置為無無有效期,也就是永久數據。
  • 如果是永久不過期數據,占用 Redis 內存太高。

方法2:使用布隆過濾器。

布隆過濾器是一種數據結構,用于快速判斷一個元素是否存在于一個集合中。具體來說,布隆過濾器包含一個位數組和一組哈希函數。位數組的初始值全部置為 0。在插入一個元素時,將該元素經過多個哈希函數映射到位數組上的多個位置,并將這些位置的值置為 1。

在查詢一個元素是否存在時,會將該元素經過多個哈希函數映射到位數組上的多個位置,如果所有位置的值都為 1,則認為元素存在;如果存在任一位置的值為 0,則認為元素不存在。

優點:

  • 高效地判斷一個元素是否屬于一個大規模集合。
  • 節省內存。

缺點:

  • 可能存在一定的誤判。
布隆過濾器誤判理解
  • 布隆過濾器要設置初始容量。容量設置越大,沖突幾率越低。
  • 布隆過濾器會設置預期的誤判值。
誤判能否接受

布隆過濾器的誤判是否能夠接受?

答:可以容忍。為什么?因為用戶名不是特別重要的數據,如果說我設置用戶名為 aaa,系統返回我不可用,那我大可以在 aaa 的基礎上再加一個a,也就是 aaaa。

布隆過濾器的使用:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
spring:data:redis:host: 127.0.0.1port: 6379password: 123456

創建布隆過濾器實例:

import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 布隆過濾器配置*/
@Configuration
public class RBloomFilterConfiguration {/*** 防止用戶注冊查詢數據庫的布隆過濾器*/@Beanpublic RBloomFilter<String> userRegisterCachePenetrationBloomFilter(RedissonClient redissonClient) {RBloomFilter<String> cachePenetrationBloomFilter = redissonClient.getBloomFilter("xxx");cachePenetrationBloomFilter.tryInit(0, 0);return cachePenetrationBloomFilter;}
}

tryInit 有兩個核心參數:

  • expectedInsertions:預估布隆過濾器存儲的元素長度。
  • falseProbability:運行的誤判率。

錯誤率越低,位數組越長,布隆過濾器的內存占用越大。

錯誤率越低,散列 Hash 函數越多,計算耗時較長。

一個布隆過濾器占用大小的在線網站:Bloom Filter Calculator

使用布隆過濾器的兩種場景:

  • 初始使用:注冊用戶時就向容器中新增數據,就不需要任務向容器存儲數據了。
  • 使用過程中引入:讀取數據源將目標數據刷到布隆過濾器。
private final RBloomFilter<String> userRegisterCachePenetrationBloomFilter;/*** 查詢用戶名是否存在* @param username* @return 存在,true 不存在,false*/@Overridepublic Boolean hashUsername(String username) {return userRegisterCachePenetrationBloomFilter.contains(username);}
用戶注冊:

一定要記得寫枚舉的時候是用逗號分割。

redis使用:

由于很久沒用過redis了,所以我忘記了怎么啟動了。

可以參考這個文檔,為了防止下一次找不到redis文件了,記得一定要配置環境變量。

redis的啟動需要先打開redis-server.exe然后再用可視化工具連接即可。

如果redis沒有密碼,但是本地application.yml又配置了redis密碼,就會導致報錯:Factory method 'redisson' threw exception with message: Unable to connect to Redis server: 127.0.0.1/127.0.0.1:6379

Window下Redis的安裝和部署詳細圖文教程(Redis的安裝和可視化工具的使用)_redis安裝-CSDN博客

自動填充字段

自動填充字段 | MyBatis-Plus

難點:

由于在注冊時,將用戶記錄添加到數據庫時,同時將用戶名添加到布隆過濾器中。但是為了防止redis的主節點掛掉后,從節點變成主節點時,有些數據還沒復制,就會導致臟數據,就會可能導致用戶名重復,所以為了防止這個情況,我們需要將username設置為唯一索引,讓數據庫兜底。

如何防止惡意請求毫秒級觸發大量請求去一個未注冊的用戶名?

因為用戶名沒注冊,所以布隆過濾器不存在,代表著可以觸發注冊流程插入數據庫。但是如果惡意請求短時間海量請求,這些請求都會落到數據庫,造成數據庫訪問壓力。這里通過分布式鎖,鎖定用戶名進行串行執行,防止惡意請求利用未注冊用戶名將請求打到數據庫。

用redisson實現分布式鎖。

UserServiceImpl:

private final RedissonClient redissonClient;/*** 注冊用戶** @param requestParam*/@Overridepublic void register(UserRegisterReqDTO requestParam) {if(hashUsername(requestParam.getUsername())){throw new ClientException(UserErrorCodeEnum.USER_NAME_EXIST);}RLock lock = redissonClient.getLock(LOCK_USER_REGISTER_KEY+requestParam.getUsername());try{if(lock.tryLock()){int inserted=baseMapper.insert(BeanUtil.toBean(requestParam,UserDO.class));if(inserted<1){throw new ClientException(UserErrorCodeEnum.USER_SAVE_ERROR);}userRegisterCachePenetrationBloomFilter.add(requestParam.getUsername());return;}throw new ClientException(UserErrorCodeEnum.USER_NAME_EXIST);}finally {lock.unlock();}}

/*** 短鏈接后管 Redis 緩存常量類* 類描述: RedisCacheConstant**/
public class RedisCacheConstant {public static final String LOCK_USER_REGISTER_KEY="short-link:lock_user-register:";
}

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

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

相關文章

異步加載與動態加載

異步加載和動態加載在概念上有相似之處&#xff0c;但并不完全等同。 異步加載&#xff08;Asynchronous Loading&#xff09;通常指的是不阻塞后續代碼執行或頁面渲染的數據或資源加載方式。在Web開發中&#xff0c;異步加載常用于從服務器獲取數據&#xff0c;而不需要用戶等…

昇思25天學習打卡營第12天|ResNet50遷移學習

昇思25天學習打卡營第12天|ResNet50遷移學習 前言ResNet50遷移學習數據準備下載數據集 加載數據集數據集可視化 訓練模型構建Resnet50網絡固定特征進行訓練訓練和評估可視化模型預測 個人任務打卡&#xff08;讀者請忽略&#xff09;個人理解與總結 前言 非常感謝華為昇思大模型…

vite簡介

vite是新一代前端構建工具&#xff0c;vite具有優勢如下&#xff1a; 輕量快速的熱重載&#xff08;HMR&#xff09;&#xff0c;能實現快速的服務啟動。對TypeScript、JSX、CSS等支持開箱即用。真正的按需編譯&#xff0c;不再等待整個應用編譯完成。webpack構建與vite構建對…

Java 遍歷Map的方法

在Java中遍歷Map可以采用以下幾種常見方法&#xff1a; 1、使用 entrySet 遍歷 這是最常見的遍歷方式&#xff0c;同時訪問鍵值對。 for (Map.Entry<K, V> entry : map.entrySet()) {K key entry.getKey();V value entry.getValue();// 處理鍵值對} 2、遍歷 keySet 后…

【Java】CompletableFuture+Mockito單元測試不通過 Unnecessary stubbings detected

文章目錄 問題描述問題分析解決Thread.sleepget()Mockito.lenient() 問題描述 有個接口使用CompletableFuture實現的異步調用&#xff0c;現在要用Mockito寫單元測試 Testpublic void updateNumAsync() {Integer newNum 600;// updateRoleCountAsync用CompletableFuture異步調…

Jenkins 強制殺job

有時候有的jenkins job運行時間太長&#xff0c;在jenkins界面點擊x按鈕進行abort&#xff0c;會失敗&#xff1a; 這時候點擊&#xff1a; “Click here to forcibly terminate running steps” 會進一步kill 任務&#xff0c;但是也還是有殺不掉的可能性。 終極武器是jenkin…

vue3【提效】使用 VueUse 高效開發(工具庫 @vueuse/core + 新增的組件庫 @vueuse/components)

Vueuse 是一個功能強大的 Vue.js 生態系統工具庫&#xff0c;提供了可重用的組件和函數&#xff0c;幫助開發者更輕松地構建復雜的應用程序。 官網 &#xff1a;https://vueuse.org/core/useWindowScroll/ 安裝 VueUse npm i vueuse/core vueuse/components&#xff08;可選&a…

llm學習-4(llm和langchain)

langchain說明文檔&#xff1a;langchain 0.2.6 — &#x1f99c;&#x1f517; langChain 0.2.6https://api.python.langchain.com/en/latest/langchain_api_reference.html#module-langchain.chat_models 1&#xff1a;模型 &#xff08;1&#xff09;自定義模型導入&#x…

跟《經濟學人》學英文:2024年07月06日這期 Amazon turns 30

As Amazon turns 30, three factors will define its next decade It will have to deal with trustbusters, catch up on AI and revive its core business 它將不得不應對反壟斷者&#xff0c;追趕人工智能并重振其核心業務 trustbuster&#xff1a; 美 [?tr?s(t)?b?s…

Java中的算法優化與復雜度分析

Java中的算法優化與復雜度分析 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在軟件開發中&#xff0c;算法的效率直接影響到程序的性能和響應速度。算法優化…

你真的會ELISA加樣嗎?

在ELISA實驗中&#xff0c;研究人員需要進行多次加樣步驟完成實驗操作。對于常規雙抗體夾心法ELISA&#xff0c;一般有如下加樣步聚&#xff0c;即加樣本、加檢測抗體、加酶結合物、加底物&#xff08;最后加終止液停止反應&#xff09;。 加樣步驟基礎知識 加樣步驟中一般使用…

云倉酒莊北京公司2024年:深耕酒業生態,以專業筑基

云倉酒莊北京公司&#xff1a;深耕酒業生態&#xff0c;以專業筑基&#xff0c;共繪酒業新藍圖 在競爭日益激烈的酒類市場中&#xff0c;云倉酒莊北京公司以其穩健的步伐、專業底蘊以及對品質的不懈追求&#xff0c;正逐步成為行業內一股不可忽視的力量。這家公司不僅僅是一個…

高級java每日一道面試題-2024年7月5日

題目&#xff1a; 請描述 Java 中接口和抽象類的區別&#xff0c;并說明什么時候應該使用接口&#xff0c;什么時候應該使用抽象類。 解答&#xff1a; 接口和抽象類都是 Java 中用于實現面向對象編程的重要概念&#xff0c;但它們在功能和用法上有一些區別&#xff1a; 1.…

把Windows打造成一個NTP網絡時間服務器,為網關提供校時服務

把Windows打造成一個NTP網絡時間服務器&#xff0c;為網關提供校時服務。主要目的是為了解決&#xff1a;當網關不能上外網的時候&#xff0c;可以使用局域網的電腦來當做NTP服務器&#xff0c;實現校時功能。 跟著小編來看&#xff0c;如何使用NTP網絡時間服務器來同步時間。 …

Laravel為什么會成為最優雅的PHP框架?

引言 在現代Web開發中&#xff0c;選擇一個合適的框架是構建高效、可靠和可維護應用的關鍵。從簡單的博客到復雜的企業級應用&#xff0c;PHP框架一直在不斷演變和進步。其中&#xff0c;Laravel作為一個相對較新的框架&#xff0c;自2011年首次發布以來&#xff0c;迅速崛起并…

ubuntu關于docker部署 項目一站式教程

**假設已有ubuntu服務器并且登錄root賬號 ** **FinalShell中復制快捷鍵是 ****Ctrl+Shift+V** 卸載老版本docker sudo apt-get remove docker docker-engine docker.io containerd runc安裝docker步驟 更新軟件包sudo apt update sudo apt upgrade安裝docker依賴sudo apt-get …

監控工具 Prometheus

監控工具 Prometheus Prometheus 是一個開源的監控解決方案&#xff0c;它能夠收集、存儲和查詢指標數據&#xff0c;并提供了強大的報警和可視化功能。Prometheus 適用于監控云原生應用程序和基礎設施&#xff0c;是 Kubernetes 生態系統中常用的監控工具之一。 1. Promethe…

Yarn有哪些功能特點

Yarn是一個由Facebook團隊開發&#xff0c;并聯合Google、Exponent和Tilde等公司推出的JavaScript包管理工具&#xff0c;旨在提供更優的包管理體驗&#xff0c;解決npm&#xff08;Node Package Manager&#xff09;的一些痛點。Yarn的功能特點主要包括以下幾個方面&#xff1…

分享 10個簡單實用的 JS 代碼技巧

代碼圖片生成工具&#xff1a;有碼高清 一、滾動到頁面頂部 我們可以使用 window.scrollTo() 平滑滾動到頁面頂部。 源碼&#xff1a; const scrollToTop () > {window.scrollTo({ top: 0, left: 0, behavior: "smooth" }); };二、滾動到頁面底部 當然&…

漢王、繪王簽字版調用封裝

說明 需要配合漢王或繪王簽字版驅動以及對應的sdk服務使用 constants.js //漢王、繪王sdk websocket連接地址 export const WS_URLS {1:ws://127.0.0.1:29999, //漢王2:ws://127.0.0.1:7181, }export const COMMAND1 {1: {HWPenSign: "HWStartSign",nLogo: "…