關(guān)于數(shù)據(jù)脫敏蚯撩,Spring boot 有話說

前言

在項目開發(fā)過程中,有一些特殊場景需要對敏感數(shù)據(jù)進行脫敏返回展示烛占,比如用戶的手機號胎挎、證件號、真實姓名忆家、郵箱等犹菇,返回如:176****9331 之類的,怎么實現(xiàn)呢芽卿?

使用@JsonSerialize對數(shù)據(jù)進行格式化

首先项栏,來看個簡單的例子,數(shù)據(jù)庫有個20位的Long 類型的ID蹬竖,返回到前端之后沼沈,因為前端類型問題,會丟失精度币厕,這個時候列另,我們就需要將Long 類型的數(shù)據(jù)格式化為String類型進行返回,代碼如下:

@Data
public class Demo {

  /** 數(shù)據(jù)ID **/
  @JsonSerialize(using = StringSerializer.class)
  private Long id;
}

上面的代碼旦装,只需要在字段添加 @JsonSerialize(using = StringSerializer.class) 注解就可以完成Long 返回 String 的格式化效果页衙。接下來,我們看看 StringSerializer 做了什么事情阴绢,源碼:

public final class StringSerializer extends StdScalarSerializer<Object> {
    private static final long serialVersionUID = 1L;

    public StringSerializer() {
        super(String.class, false);
    }

    public boolean isEmpty(SerializerProvider prov, Object value) {
        String str = (String)value;
        return str.isEmpty();
    }
    // 主要關(guān)注這個方法店乐,這個是序列化方法
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        // 將 object 直接轉(zhuǎn)換成 String 返回
        gen.writeString((String)value);
    }

    public final void serializeWithType(Object value, JsonGenerator gen, SerializerProvider provider, TypeSerializer typeSer) throws IOException {
        gen.writeString((String)value);
    }

    public JsonNode getSchema(SerializerProvider provider, Type typeHint) {
        return this.createSchemaNode("string", true);
    }

    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException {
        this.visitStringFormat(visitor, typeHint);
    }
}

其實,只需要關(guān)注 serialize 這個方法呻袭,其他方法都是對其進行的增強眨八,我們先看看StringSerializer 的UML 關(guān)系圖:

這個時候我們就會發(fā)現(xiàn)serialize() 其實是JsonSerializer 的抽象方法,來看看 JsonSerializer 源碼:

public abstract class JsonSerializer<T> implements JsonFormatVisitable {
    public JsonSerializer() {
    }

    public JsonSerializer<T> unwrappingSerializer(NameTransformer unwrapper) {
        return this;
    }

    public JsonSerializer<T> replaceDelegatee(JsonSerializer<?> delegatee) {
        throw new UnsupportedOperationException();
    }

    public JsonSerializer<?> withFilterId(Object filterId) {
        return this;
    }
    // 序列化抽象方法
    public abstract void serialize(T var1, JsonGenerator var2, SerializerProvider var3) throws IOException;

    public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {
        Class<?> clz = this.handledType();
        if (clz == null) {
            clz = value.getClass();
        }

        serializers.reportBadDefinition(clz, String.format("Type id handling not implemented for type %s (by serializer of type %s)", clz.getName(), this.getClass().getName()));
    }

    public Class<T> handledType() {
        return null;
    }

    /** @deprecated */
    @Deprecated
    public boolean isEmpty(T value) {
        return this.isEmpty((SerializerProvider)null, value);
    }

    public boolean isEmpty(SerializerProvider provider, T value) {
        return value == null;
    }

    public boolean usesObjectId() {
        return false;
    }

    public boolean isUnwrappingSerializer() {
        return false;
    }

    public JsonSerializer<?> getDelegatee() {
        return null;
    }

    public Iterator<PropertyWriter> properties() {
        return ClassUtil.emptyIterator();
    }

    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {
        visitor.expectAnyFormat(type);
    }

    public abstract static class None extends JsonSerializer<Object> {
        public None() {
        }
    }
}

分析到這里左电,聰明的小伙伴是不是精神一震廉侧,我了個擦页响,那我是不是可以自己繼承這個超級類,實現(xiàn)自己的格式化邏輯(比如:脫敏~6翁堋H虿稀!)连舍!沒錯了没陡,就是這樣,下面我們繼續(xù)看索赏,怎么去實現(xiàn)數(shù)據(jù)脫敏盼玄。

對手機號進行脫敏處理

開始之前,推進一款開源工具框架参滴,只要你能想到的强岸,這個工具基本上都支持锻弓,而且還是國產(chǎn)砾赔,那就是: hutool

首先青灼,引入依賴(spring boot 自行引入):

<dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>${hutool.version}</version>
</dependency>

繼承JsonSerializer 并實現(xiàn) serialize 抽象方法:

public class PhoneDesensitizationSerializer extends JsonSerializer<String> {
    @Override
    public void serialize(String phone, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        String phoneDesensitization = DesensitizedUtil.mobilePhone(phone);
        jsonGenerator.writeString(phoneDesensitization);
    }
}

最后暴心,使用PhoneDesensitizationSerializer 對說幾號進行脫敏:

public class UserInfo {

    // 省略其他字段
    @JsonSerialize(using = PhoneDesensitizationSerializer.class)
    private String phoneNumber;
    
    // 省略其他字段
}

完活,其他的脫敏思路都是一樣的杂拨,無非就是copy 改一下tool 方法专普。

總結(jié)

在遇到一個問題時,一定要多想弹沽,因為我們能遇到檀夹,別人一定也會遇到,總會找到快速解決問題的辦法策橘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載炸渡,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。
  • 序言:七十年代末丽已,一起剝皮案震驚了整個濱河市蚌堵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沛婴,老刑警劉巖吼畏,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嘁灯,居然都是意外死亡泻蚊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門丑婿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來藕夫,“玉大人孽糖,你說我怎么就攤上這事∫阒” “怎么了办悟?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長滩褥。 經(jīng)常有香客問我病蛉,道長,這世上最難降的妖魔是什么瑰煎? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任铺然,我火速辦了婚禮,結(jié)果婚禮上酒甸,老公的妹妹穿的比我還像新娘魄健。我一直安慰自己,他們只是感情好插勤,可當(dāng)我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布沽瘦。 她就那樣靜靜地躺著,像睡著了一般农尖。 火紅的嫁衣襯著肌膚如雪析恋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天盛卡,我揣著相機與錄音助隧,去河邊找鬼。 笑死滑沧,一個胖子當(dāng)著我的面吹牛并村,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播滓技,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼哩牍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了殖属?” 一聲冷哼從身側(cè)響起姐叁,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎洗显,沒想到半個月后外潜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡挠唆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年处窥,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玄组。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡滔驾,死狀恐怖谒麦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哆致,我是刑警寧澤绕德,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站摊阀,受9級特大地震影響耻蛇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胞此,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一臣咖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漱牵,春花似錦夺蛇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至灵临,卻和暖如春截型,著一層夾襖步出監(jiān)牢的瞬間趴荸,已是汗流浹背儒溉。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留发钝,地道東北人顿涣。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像酝豪,于是被迫代替她去往敵國和親涛碑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,955評論 2 355