基于java實現(xiàn)一個脫敏組件
功能說明
因為最近有脫敏的需求,所以就趁著這個機會自己實現(xiàn)了一個??隙ㄟ€有不少開源庫有這種功能,但是考慮到不一定滿足自己的需要,所以就自己造了一個輪子自己用。主要功能包括
- 接口返回內(nèi)容的脫敏,包含json序列化方式和aop的兩種實現(xiàn)。
- json序列化方式只能用于接口數(shù)據(jù)返回,在程序內(nèi)部和數(shù)據(jù)庫并不脫敏。
- aop的方式,在程序內(nèi)部和接口數(shù)據(jù)返回時可以脫敏,但是數(shù)據(jù)庫不脫敏,且速度是慢于序列化方式的。
- 根據(jù)自己的需求來實現(xiàn)脫敏規(guī)則,比如有些人的手機號脫敏是中間四位,有些人又只保留初始和末尾一位。
- 自定義脫敏字符,默認(rèn)為
*。 - 請求體數(shù)據(jù)自動過濾,比如你傳向前端的數(shù)據(jù)是包含脫敏字符的,正常的做法是前端判斷時候包含脫敏字符,如果包含則該字段不往后端傳輸。我這邊實現(xiàn)的是,如果請求體傳過來的數(shù)據(jù)內(nèi)容跟改字段的脫敏規(guī)則一致則不接收該字段內(nèi)容,不,準(zhǔn)確的說是在接收該字段內(nèi)容之前轉(zhuǎn)為null。
使用示例
總共有四種使用場景:
1.作用與方法上的aop注解
@Desensitizes({@Desensitize(field = "username", exclude = true), @Desensitize(field = "phoneNumber", type = MobilePhoneDesensitizer.class), @Desensitize(field = "email", type = EmailDesensitizer.class, maskChar = "#")})
@GetMapping("/testMethodAnno")
public TestNoAnnoVO testMethodAnno() {
TestNoAnnoVO test = new TestNoAnnoVO();
test.setUsername("JohnDoe");
test.setPhoneNumber("13812345678");
test.setEmail("john.doe@example.com");
return test;
}
@Data
public class TestNoAnnoVO {
private String username;
private String phoneNumber;
private String email;
}
輸出內(nèi)容為:

2.作用于實體字段的aop注解
@GetMapping("/testFieldAnno")
public TestVO testFieldAnno() {
TestVO test = new TestVO();
test.setUsername("JohnDoe");
test.setPhoneNumber("13812345678");
test.setEmail("john.doe@example.com");
test.setIdCard("123456199001011234");
return test;
}
public class TestVO {
@Desensitize(exclude = true)
private String username;
@Desensitize(type = MobilePhoneDesensitizer.class)
private String phoneNumber;
@Desensitize(type = EmailDesensitizer.class, maskChar = "#")
private String email;
@Desensitize(type = IDCardDesensitizer.class, maskChar = "%")
private String idCard;
}
輸出內(nèi)容為:

3.序列化注解
@GetMapping("/testJsonAnno")
public TestJsonVO testJsonAnno() {
TestJsonVO test = new TestJsonVO();
test.setUsername("JohnDoe");
test.setPhoneNumber("13812345678");
test.setEmail("j@example.com");
test.setIdCard("123456199001011234");
return test;
}
@Data
public class TestJsonVO {
@JsonDesensitize(exclude = true)
private String username;
@JsonDesensitize(type = MobilePhoneDesensitizer.class)
private String phoneNumber;
@JsonDesensitize(type = EmailDesensitizer.class, maskChar = "#")
private String email;
@JsonDesensitize(type = IDCardDesensitizer.class)
private String idCard;
}
這個有些區(qū)別,如果設(shè)置了exclude為true,則直接將返回的該字段隱去。輸出內(nèi)容為:

最后就是基于@JsonDesensitize額外加了一個屬性ignoreDesensitized,用于判斷是否在接收數(shù)據(jù)時排除脫敏內(nèi)容。
@PostMapping("testPut")
public void testPut(@RequestBody TestDTO testDTO) {
log.info("接收到的數(shù)據(jù)內(nèi)容為{}", testDTO.toString());
}
@Data
public class TestDTO {
@JsonDesensitize(exclude = true, ignoreDesensitized = true)
private String username;
@JsonDesensitize(type = MobilePhoneDesensitizer.class, ignoreDesensitized = true)
private String phoneNumber;
@JsonDesensitize(type = EmailDesensitizer.class, maskChar = "#", ignoreDesensitized = true)
private String email;
@JsonDesensitize(type = IDCardDesensitizer.class, ignoreDesensitized = true)
private String idCard;
}
使用效果為:

這個是嚴(yán)格按照輸出時的脫敏匹配的,比如輸出時手機號脫敏內(nèi)容為138****1234,那么136****4321則不會接收,正常沒有*的手機號或者不符合該規(guī)則的比如13****51234這種也會被正常接收。當(dāng)然這個規(guī)則是可以在項目中自定義的。
使用說明
項目地址
github.com/chenqi92/alltobs-desensitization-all 里面包含待引入的jar和demo,因為剛寫完,簡單測試了一下不排除有其他bug,有需要可以自己fork一下自己改。后續(xù)我會在項目中實際使用,如果發(fā)現(xiàn)有bug會不斷更新,當(dāng)然也歡迎提issuses。
引入jar
<dependency>
<groupId>com.alltobs</groupId>
<artifactId>alltobs-desensitization</artifactId>
<version>1.0.0</version>
</dependency>
工具已經(jīng)上傳到了maven的中央倉庫,國內(nèi)的用戶可能存在下載困難等問題,需要科學(xué)一下。使用國內(nèi)的阿里等平臺代理,以我以往經(jīng)驗同步過去起碼要半個月把。

啟用功能
啟動類添加注解@EnableAllbsDesensitization
根據(jù)自己使用場景的需要、以及上述示例來選擇性的添加注解
@Desensitize
@Desensitizes
@JsonDesensitize
自定義在項目中實現(xiàn)一個自己需要的脫敏方式
如果你不想用默認(rèn)的脫敏方式,實際上我也沒寫幾個,后續(xù)應(yīng)該會接著加。 那么就在你的項目工程中自定義集成BaseDesensitizer類然后自己實現(xiàn)desensitize和getDesensitizedRegex方法即可。 這兩個方法一個是用于脫敏規(guī)則,一個是用于接收數(shù)據(jù)時判斷是否符合規(guī)則。 具體實現(xiàn)以身份證號為例:
package com.alltobs.alltobsdesensitizationdemo.desensitizer;
import com.alltobs.desensitization.desensitizer.BaseDesensitizer;
import java.util.regex.Pattern;
/**
* 類 IDCardDesensitizer
* * @author ChenQi
* @date 2024/11/11
*/public class IDCardDesensitizer extends BaseDesensitizer {
@Override
public String desensitize(String value, String maskChar) {
if (value != null && (value.length() == 15 || value.length() == 18)) {
// 脫敏中間部分
int prefixLength = 6;
int suffixLength = 4;
int maskLength = value.length() - prefixLength - suffixLength;
String prefix = value.substring(0, prefixLength);
String suffix = value.substring(value.length() - suffixLength);
String maskedSection = maskChar.repeat(maskLength);
return prefix + maskedSection + suffix;
}
return value;
}
@Override
public String getDesensitizedRegex(String maskChar) {
String escapedMaskChar = Pattern.quote(maskChar);
// 身份證號可能是 15 位或 18 位,這里統(tǒng)一處理
String maskPattern = escapedMaskChar + "+";
return "^\\d{6}" + maskPattern + "\\d{4}$";
}
}

以上就是基于java實現(xiàn)一個脫敏組件的詳細內(nèi)容,更多關(guān)于java脫敏組件的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java 字節(jié)碼與Smali 語法基礎(chǔ)實戰(zhàn)案例
本文介紹了Java字節(jié)碼(.class)和DEX字節(jié)碼(.dex)的基本概念、轉(zhuǎn)換流程及優(yōu)化特性,對比了JVM和Dalvik虛擬機的區(qū)別,并詳細講解了Smali語法基礎(chǔ),感興趣的朋友跟隨小編一起看看吧2026-01-01
SpringBoot集成MiniMax和CosyVoice實現(xiàn)文本轉(zhuǎn)語音功能
在一些需要高質(zhì)量文本轉(zhuǎn)語音(TTS)的場景中(比如:有聲書配音、播客等),比較推薦使用MiniMax、CosyVoice這些提供的音色,這些音色的效果會更加擬人、逼真,接近真人發(fā)音,本文將引導(dǎo)讀者從零到一把MiniMax、CosyVoice的語音合成能力整合到你的SpringBoot應(yīng)用中2025-10-10
spring?boot?+?mybatis使用線程池異步修改數(shù)據(jù)庫數(shù)據(jù)的步驟
MyBatis與Spring?Boot的整合,可以通過注解式配置實現(xiàn)數(shù)據(jù)訪問層的無縫對接,使得數(shù)據(jù)庫操作更加直觀和高效,這篇文章主要介紹了spring?boot?+?mybatis使用線程池異步修改數(shù)據(jù)庫數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2025-09-09
java動態(tài)規(guī)劃算法——硬幣找零問題實例分析
這篇文章主要介紹了java動態(tài)規(guī)劃算法——硬幣找零問題,結(jié)合實例形式分析了java動態(tài)規(guī)劃算法——硬幣找零問題相關(guān)原理、實現(xiàn)方法與操作注意事項,需要的朋友可以參考下2020-05-05
java8中定時任務(wù)最佳實現(xiàn)方式(實現(xiàn)原理)
這篇文章主要介紹了java8中定時任務(wù)最佳實現(xiàn)方式,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-12-12

