SpringBoot接口數(shù)據(jù)如何實(shí)現(xiàn)優(yōu)雅的脫敏問(wèn)題
實(shí)現(xiàn)方案:自定義注解 + Jackson序列化器
1.具體代碼
自定義脫敏注解:
package org.springblade.common.annotation; import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.springblade.common.config.SensitiveJsonSerializer; import org.springblade.common.enums.SensitiveTypeEnum; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 脫敏注解 * * @author hf * @since 2023/6/14 **/ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @JacksonAnnotationsInside @JsonSerialize(using = SensitiveJsonSerializer.class) public @interface Desensitized { /** * 脫敏類(lèi)型(規(guī)則) */ SensitiveTypeEnum type(); }
脫敏類(lèi)型枚舉類(lèi):支持用戶(hù)名、手機(jī)號(hào)、身份證號(hào)、地址
package org.springblade.common.enums; import java.util.function.Function; /** * 脫敏類(lèi)型枚舉 * * @author hf * @since **/ public enum SensitiveTypeEnum { /** * 用戶(hù)名 */ USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")), /** * 身份證 */ ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")), /** * 手機(jī)號(hào) */ MOBILE_PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), /** * 地址 */ ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****")); private final Function<String, String> desensitizer; SensitiveTypeEnum(Function<String, String> desensitizer) { this.desensitizer = desensitizer; } public Function<String, String> desensitizer() { return desensitizer; } }
序列化注解自定義實(shí)現(xiàn):
package org.springblade.common.config; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.ContextualSerializer; import org.springblade.common.annotation.Desensitized; import org.springblade.common.enums.SensitiveTypeEnum; import java.io.IOException; import java.util.Objects; /** * 序列化注解自定義實(shí)現(xiàn) * JsonSerializer<String>:指定String 類(lèi)型,serialize()方法用于將修改后的數(shù)據(jù)載入 */ public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer { private SensitiveTypeEnum strategy; @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(strategy.desensitizer().apply(value)); } /** * 獲取屬性上的注解屬性 */ @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { Desensitized annotation = property.getAnnotation(Desensitized.class); if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) { this.strategy = annotation.type(); return this; } return prov.findValueSerializer(property.getType(), property); } }
2.使用方法
添加注解@Desensitized
在需要進(jìn)行脫敏的字段上添加@Desensitized注解,并選擇具體的脫敏類(lèi)型。
示例如下:
/** * 手機(jī) */ @Desensitized(type = SensitiveTypeEnum.MOBILE_PHONE) private String phone; /** * 身份證號(hào) */ @Desensitized(type = SensitiveTypeEnum.ID_CARD) private String idNo;
3.脫敏結(jié)果
3.1脫敏前數(shù)據(jù):
{ "phone": "13924369234", "idNo": "1210103199603282410", }
3.2脫敏后數(shù)據(jù):
{ "phone": "139****9234", "idNo": "1210************10", }
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- Springboot項(xiàng)目通過(guò)redis實(shí)現(xiàn)接口的冪等性
- Springboot項(xiàng)目長(zhǎng)時(shí)間不進(jìn)行接口操作,提示HikariPool-1警告的解決
- SpringBoot訪(fǎng)問(wèn)接口自動(dòng)跳轉(zhuǎn)login頁(yè)面的問(wèn)題及解決
- Springboot配置全局跨域未生效,訪(fǎng)問(wèn)接口報(bào)錯(cuò)問(wèn)題及解決
- SpringBoot中REST API 接口傳參的實(shí)現(xiàn)
- springboot接口返回?cái)?shù)據(jù)類(lèi)型全面解析
相關(guān)文章
springBoot+dubbo+zookeeper實(shí)現(xiàn)分布式開(kāi)發(fā)應(yīng)用的項(xiàng)目實(shí)踐
本文主要介紹了springBoot+dubbo+zookeeper實(shí)現(xiàn)分布式開(kāi)發(fā)應(yīng)用的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03MyBatis實(shí)現(xiàn)樂(lè)觀(guān)鎖和悲觀(guān)鎖的示例代碼
在數(shù)據(jù)庫(kù)操作中,樂(lè)觀(guān)鎖和悲觀(guān)鎖是兩種常見(jiàn)的并發(fā)控制策略,本文主要介紹了MyBatis實(shí)現(xiàn)樂(lè)觀(guān)鎖和悲觀(guān)鎖的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07Spring?cloud?實(shí)現(xiàn)房源查詢(xún)功能的實(shí)例代碼
這篇文章主要介紹了Spring?cloud?實(shí)現(xiàn)房源查詢(xún)功能,本項(xiàng)目是一個(gè)多模塊項(xiàng)目,創(chuàng)建一個(gè) Spring Initializr 項(xiàng)目 不自動(dòng)添加依賴(lài)項(xiàng),完成創(chuàng)建后刪除自帶的src目錄,并在根目錄下創(chuàng)建新的maven模塊,需要的朋友可以參考下2022-09-09Springcloud seata nacos環(huán)境搭建過(guò)程圖解
這篇文章主要介紹了Springcloud seata nacos環(huán)境搭建過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Springboot應(yīng)用中Mybatis輸出SQL日志的3種方法代碼示例
在前臺(tái)請(qǐng)求數(shù)據(jù)的時(shí)候,sql語(yǔ)句一直都是打印到控制臺(tái)的,有一個(gè)想法就是想讓它打印到日志里,該如何做呢?這篇文章主要給大家介紹了關(guān)于Springboot應(yīng)用中Mybatis輸出SQL日志的3種方法,需要的朋友可以參考下2024-01-01springboot實(shí)現(xiàn)啟動(dòng)直接訪(fǎng)問(wèn)項(xiàng)目地址
這篇文章主要介紹了springboot實(shí)現(xiàn)啟動(dòng)直接訪(fǎng)問(wèn)項(xiàng)目地址,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12JAVA 日常開(kāi)發(fā)中Websocket示例詳解
JAVA |日常開(kāi)發(fā)中Websocket詳解,WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議,它在Web應(yīng)用中實(shí)現(xiàn)了客戶(hù)端與服務(wù)器之間的實(shí)時(shí)數(shù)據(jù)傳輸,本文將詳細(xì)介紹Java開(kāi)發(fā)中WebSocket的使用,包括基本概念、Java API、使用示例以及注意事項(xiàng),感興趣的朋友一起看看吧2024-12-12