最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java使用Hutool+自定義注解實(shí)現(xiàn)數(shù)據(jù)脫敏

 更新時(shí)間:2023年09月07日 09:31:53   作者:Bummon  
我們在使用手機(jī)銀行的時(shí)候經(jīng)常能看到APP上會將銀行卡的卡號中間部分給隱藏掉使用 ***** 來代替,在某些網(wǎng)站上查看一些業(yè)務(wù)密碼時(shí)(例如簽到密碼等)也會使用 ***** 來隱藏掉真正的密碼,那么這種方式是如何實(shí)現(xiàn)的呢,本文將給大家介紹使用Hutool+自定義注解實(shí)現(xiàn)數(shù)據(jù)脫敏

前言

我們在使用手機(jī)銀行的時(shí)候經(jīng)常能看到APP上會將銀行卡的卡號中間部分給隱藏掉使用 ***** 來代替,在某些網(wǎng)站上查看一些業(yè)務(wù)密碼時(shí)(例如簽到密碼等)也會使用 ***** 來隱藏掉真正的密碼,那么這種方式是如何實(shí)現(xiàn)的呢?

Hutool

Hutool是一個小而全的Java工具類庫,通過靜態(tài)方法封裝,降低相關(guān)API的學(xué)習(xí)成本,提高工作效率,使Java擁有函數(shù)式語言般的優(yōu)雅,讓Java語言也可以“甜甜的”。

Hutool中的工具方法來自每個用戶的精雕細(xì)琢,它涵蓋了Java開發(fā)底層代碼中的方方面面,它既是大型項(xiàng)目開發(fā)中解決小問題的利器,也是小型項(xiàng)目中的效率擔(dān)當(dāng);

Hutool是項(xiàng)目中 util 包友好的替代,它節(jié)省了開發(fā)人員對項(xiàng)目中公用類和公用工具方法的封裝時(shí)間,使開發(fā)專注于業(yè)務(wù),同時(shí)可以最大限度的避免封裝不完善帶來的bug。

我們這篇文章的實(shí)現(xiàn)思路就基于Hutool來實(shí)現(xiàn),在Hutool中提供了一個名為 DesensitizedUtil 的工具類,我們使用這個工具類來加密。

首先我們先來看一下這個類里的具體實(shí)現(xiàn),如下:

我們可以看到映入眼簾的除了一個無參構(gòu)造之外就是一個名為 desensitized 的方法,這個方法就是我們加密的主要方法,里面利用了 switch…case 方法來區(qū)分不同的加密方法。我們可以來寫一個單元測試來測試一下通過這個方法加密后是什么樣的。

以上為加密后的信息,里面我使用了不同的類型來進(jìn)行加密,目前最新版的Hutool支持脫敏加密的類型如下:

  • 用戶ID
  • 中文名
  • 密碼
  • 地址
  • 郵箱
  • 座機(jī)號
  • 手機(jī)號
  • 中國大陸的車牌號
  • 銀行卡號
  • IPv4地址
  • IPv6地址
  • 自定義脫敏

實(shí)現(xiàn)

通過以上的示例我們就可以開始編寫我們自己的脫敏操作了,首先我們要先根據(jù)以上Hutool中提供的脫敏類型來編寫我們自己的類型**(如嫌麻煩也可省略此步驟,直接使用DesensitizedUtil中的DesensitizedType)**

編寫數(shù)據(jù)脫敏類型

/**
 * @author Bummon
 * @description 數(shù)據(jù)脫敏策略
 * @date 2023-09-01 17:43
 */
public enum DataMaskingType {
    /**
     * 用戶ID
     */
    USER_ID,
    /**
     * 中文名
     */
    CHINESE_NAME,
    /**
     * 身份證號
     */
    ID_CARD,
    /**
     * 座機(jī)
     */
    FIXED_PHONE,
    /**
     * 手機(jī)號
     */
    MOBILE_PHONE,
    /**
     * 地址
     */
    ADDRESS,
    /**
     * 郵箱
     */
    EMAIL,
    /**
     * 密碼
     */
    PASSWORD,
    /**
     * 中國大陸車牌號
     */
    CAR_LICENSE,
    /**
     * 銀行卡號
     */
    BANK_CARD,
    /**
     * IPv4地址
     */
    IPV4,
    /**
     * IPv6地址
     */
    IPV6,
    /**
     * 自定義類型
     */
    CUSTOM;
}

編寫自定義注解

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * @author Bummon
 * @description 數(shù)據(jù)脫敏自定義注解
 * @date 2023-09-01 18:01
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DataMaskingSerialize.class)
public @interface DataMasking {
    /**
     * 數(shù)據(jù)脫敏類型
     */
    DataMaskingType type() default DataMaskingType.CUSTOM;
    /**
     * 脫敏開始位置(包含)
     */
    int start() default 0;
    /**
     * 脫敏結(jié)束位置(不包含)
     */
    int end() default 0;
}

需要注意的是:當(dāng)DataMaskingType為 CUSTOM 時(shí),才需要填寫 start 和 end ,且這兩個參數(shù)才會生效,且 start 中是包含當(dāng)前下標(biāo)的字符的,而 end 不包含當(dāng)前下標(biāo)的字符。

編寫自定義序列化類

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.DesensitizedUtil;
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 lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import java.io.IOException;
import java.util.Objects;
/**
 * @author Bummon
 * @description
 * @date 2023-09-01 18:14
 */
@AllArgsConstructor
@NoArgsConstructor
public class DataMaskingSerialize extends JsonSerializer implements ContextualSerializer {
    private DataMaskingType type;
    private Integer start;
    private Integer end;
    @Override
    public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        String value = (String) o;
        switch (type) {
            //userId
            case USER_ID:
                jsonGenerator.writeString(String.valueOf(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.USER_ID)));
                break;
            //中文名
            case CHINESE_NAME:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.CHINESE_NAME));
                break;
            //身份證號
            case ID_CARD:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.ID_CARD));
                break;
            //座機(jī)
            case FIXED_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.FIXED_PHONE));
                break;
            //手機(jī)號
            case MOBILE_PHONE:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.MOBILE_PHONE));
                break;
            //地址
            case ADDRESS:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.ADDRESS));
                break;
            //郵箱
            case EMAIL:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.EMAIL));
                break;
            case BANK_CARD:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.BANK_CARD));
                break;
            //密碼
            case PASSWORD:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.PASSWORD));
                break;
            //中國大陸車牌號
            case CAR_LICENSE:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.CAR_LICENSE));
                break;
            case IPV4:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.IPV4));
                break;
            case IPV6:
                jsonGenerator.writeString(DesensitizedUtil.desensitized(value, DesensitizedUtil.DesensitizedType.IPV6));
                break;
            //自定義
            case CUSTOM:
                jsonGenerator.writeString(CharSequenceUtil.hide(value, start, end));
                break;
            default:
                break;
        }
    }
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (Objects.nonNull(beanProperty)) {
            //判斷是否為string類型
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                DataMasking anno = beanProperty.getAnnotation(DataMasking.class);
                if (Objects.isNull(anno)) {
                    anno = beanProperty.getContextAnnotation(DataMasking.class);
                }
                if (Objects.nonNull(anno)) {
                    return new DataMaskingSerialize(anno.type(), anno.start(), anno.end());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }
}

我們繼承于 JsonSerializer 并實(shí)現(xiàn)了 ContextualSerializer 中的方法,并對我們自定義注解聲明的字段進(jìn)行攔截和脫敏加密操作,接下來我們可以來測試一下效果。

測試

因?yàn)槭菍?shí)例化的時(shí)候才會被脫敏,那我們就創(chuàng)建一個實(shí)體類來存放我們需要加密的信息。

編寫測試實(shí)體類

import com.bummon.mask.DataMasking;
import com.bummon.mask.DataMaskingType;
import lombok.*;
/**
 * @author Bummon
 * @description
 * @date 2023-09-01 18:29
 */
@Data
@Builder
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class TestEntity {
    @DataMasking(type = DataMaskingType.USER_ID)
    private Integer userId;
    @DataMasking(type = DataMaskingType.CHINESE_NAME)
    private String userName;
    @DataMasking(type = DataMaskingType.ADDRESS)
    private String address;
    @DataMasking(type = DataMaskingType.ID_CARD)
    private String idCard;
    @DataMasking(type = DataMaskingType.FIXED_PHONE)
    private String fixedPhone;
    @DataMasking(type = DataMaskingType.MOBILE_PHONE)
    private String mobilePhone;
    @DataMasking(type = DataMaskingType.EMAIL)
    private String email;
    @DataMasking(type = DataMaskingType.PASSWORD)
    private String password;
    @DataMasking(type = DataMaskingType.CAR_LICENSE)
    private String carLicense;
    @DataMasking(type = DataMaskingType.BANK_CARD)
    private String bankCard;
    @DataMasking(type = DataMaskingType.IPV4)
    private String ipv4;
    @DataMasking(type = DataMaskingType.IPV6)
    private String ipv6;
    @DataMasking(type = DataMaskingType.CUSTOM,start = 3,end = 9)
    private String custom;
    /**
     * 不進(jìn)行數(shù)據(jù)脫敏的字段
     */
    private String noMask;
}

編寫測試Controller

import com.bummon.entity.TestEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author Bummon
 * @description
 * @date 2023-09-01 18:39
 */
@RestController
public class TestController {
    @GetMapping("/test")
    public TestEntity test() {
        return TestEntity.builder()
                .userId(1234567890)
                .userName("張三")
                .password("12")
                .address("河南省鄭州市中原區(qū)")
                .email("xxxx@xx.com")
                .fixedPhone("0838-5553792")
                .mobilePhone("13888888888")
                .carLicense("豫P3U253")
                .bankCard("1679374639283740")
                .idCard("412711223344556677")
                .ipv4("192.168.1.236")
                .ipv6("abcd:1234:aCA9:123:4567:089:0:0000")
                .custom("289073458794")
                .noMask("我是不需要數(shù)據(jù)脫敏的字段")
                .build();
    }
}

接下來我們啟動項(xiàng)目來看測試一下得到的是否為我們預(yù)期的數(shù)據(jù):

我們可以看到,我們加了注解的字段都被正確的脫敏了,而沒加注解的字段會正常顯示。

總結(jié)

我們使用了HutoolDesensitizedUtil中的 desensitized 方法來實(shí)現(xiàn)數(shù)據(jù)脫敏,在 CUSTOM 類型的脫敏字段中,startend 兩個屬性是必填的,且 start 包含當(dāng)前下標(biāo),而 end 不包含當(dāng)前下標(biāo)。

以上就是Java使用Hutool+自定義注解實(shí)現(xiàn)數(shù)據(jù)脫敏的詳細(xì)內(nèi)容,更多關(guān)于Hutool+自定義注解數(shù)據(jù)脫敏的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 編寫Java代碼制造一個內(nèi)存溢出的情況

    編寫Java代碼制造一個內(nèi)存溢出的情況

    這篇文章主要介紹了編寫Java代碼制造一個內(nèi)存溢出的情況,或許這種有意制造能夠更好地幫助理解Java中的內(nèi)存溢出情況XD 需要的朋友可以參考下
    2015-07-07
  • MyBatis多表查詢和注解開發(fā)案例詳解

    MyBatis多表查詢和注解開發(fā)案例詳解

    這篇文章主要介紹了MyBatis多表查詢和注解開發(fā),本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • Java實(shí)現(xiàn)動態(tài)日歷效果

    Java實(shí)現(xiàn)動態(tài)日歷效果

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)動態(tài)日歷效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • 基于Java實(shí)現(xiàn)修改圖片分辨率示例代碼

    基于Java實(shí)現(xiàn)修改圖片分辨率示例代碼

    這篇文章主要介紹了一個可以修改圖片分辨率的java工具類,文中的示例代碼講解詳細(xì),對學(xué)習(xí)JAVA有一定的幫助,感興趣的小伙伴快來跟隨小編一起學(xué)習(xí)吧
    2021-12-12
  • java如何創(chuàng)建普通二叉樹

    java如何創(chuàng)建普通二叉樹

    這篇文章主要介紹了java如何創(chuàng)建普通二叉樹的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring 整合 MyBatis的實(shí)現(xiàn)步驟

    Spring 整合 MyBatis的實(shí)現(xiàn)步驟

    SpringMVC 本來就是 Spring 框架的一部分,這兩者無須再做整合,所以 SSM 整合的關(guān)鍵就是Spring對MyBatis的整合,三大框架整合完成后,將以 Spring 為核心,調(diào)用有關(guān)資源,高效運(yùn)作,這篇文章主要介紹了 Spring 整合 MyBatis的實(shí)現(xiàn)步驟,需要的朋友可以參考下
    2023-02-02
  • Springboot+jwt實(shí)現(xiàn)在線用戶功能(示例代碼)

    Springboot+jwt實(shí)現(xiàn)在線用戶功能(示例代碼)

    這篇文章主要介紹了Springboot+jwt實(shí)現(xiàn)在線用戶功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • Spring MVC 處理Ajax請求的方式詳解

    Spring MVC 處理Ajax請求的方式詳解

    本文介紹了在SpringMVC中處理Ajax請求的方法,主要依賴于Controller和返回類型的配置,使用@RequestMapping注解處理Ajax的控制器方法,本文給大家介紹Spring MVC 處理Ajax請求的方式,感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • Java安全之CC1利用鏈詳解

    Java安全之CC1利用鏈詳解

    這篇文章主要介紹了Java安全之CC1利用鏈的使用方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • 舉例說明Java中代碼塊的執(zhí)行順序

    舉例說明Java中代碼塊的執(zhí)行順序

    這篇文章主要介紹了舉例說明Java中代碼塊的執(zhí)行順序,包括靜態(tài)屬性和非靜態(tài)屬性以及構(gòu)造函數(shù)等相關(guān)的執(zhí)行先后,需要的朋友可以參考下
    2015-07-07

最新評論

营山县| 丰台区| 神池县| 平昌县| 卓资县| 和顺县| 达拉特旗| 崇义县| 余江县| 乾安县| 海城市| 乌鲁木齐县| 漯河市| 溧阳市| 盐池县| 英吉沙县| 广南县| 新化县| 延吉市| 青海省| 汉中市| 锦屏县| 寿宁县| 科技| 新密市| 阳信县| 台东县| 修水县| 葫芦岛市| 大足县| 介休市| 松潘县| 花莲县| 磐安县| 河西区| 胶南市| 萨迦县| 东丽区| 勃利县| 日照市| 丰都县|