首先说到脱敏问题,我相信在座的很多人都需要处理这样的场景,比如前端页面显示的身份证号、地址等敏感信息都需要脱敏处理,而hutool就有这样的一个工具来辅助我们完成对某些字段属性信息的脱敏,hutool没有现成的实现方式,只是借助这个工具帮助我们来具体实现
前言
我们在使用手机银行的时候经常能看到APP上会将银行卡的卡号中间部分给隐藏掉使用 ***** 来代替,在某些网站上查看一些业务密码时(例如签到密码等)也会使用 ***** 来隐藏掉真正的密码,那么这种方式是如何实现的呢?
我们这篇文章的实现思路就基于Hutool来实现,在Hutool中提供了一个名为 DesensitizedUtil 的工具类,我们使用这个工具类来加密。
首先我们先来看一下这个类里的具体实现,如下:
我们可以看到映入眼帘的除了一个无参构造之外就是一个名为 desensitized 的方法,这个方法就是我们加密的主要方法,里面利用了 switch…case 方法来区分不同的加密方法。我们可以来写一个单元测试来测试一下通过这个方法加密后是什么样的
以上为加密后的信息,里面我使用了不同的类型来进行加密,目前最新版的Hutool支持脱敏加密的类型如下:
- 用户ID
- 中文名
- 密码
- 地址
- 邮箱
- 座机号
- 手机号
- 中国大陆的车牌号
- 银行卡号
- IPv4地址
- IPv6地址
- 自定义脱敏
具体实现demo
通过以上的示例我们就可以开始编写我们自己的脱敏操作了,首先我们要先根据以上Hutool中提供的脱敏类型来编写我们自己的类型**(如嫌麻烦也可省略此步骤,直接使用DesensitizedUtil中的DesensitizedType)**
编写数据脱敏类型
/**
* @author Bummon
* @description 数据脱敏策略
* @date 2023-09-01 17:43
*/
public enum DataMaskingType {
/**
* 用户ID
*/
USER_ID,
/**
* 中文名
*/
CHINESE_NAME,
/**
* 身份证号
*/
ID_CARD,
/**
* 座机
*/
FIXED_PHONE,
/**
* 手机号
*/
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;
/**
* @description 数据脱敏自定义注解
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DataMaskingSerialize.class)
public @interface DataMasking {
/**
* 数据脱敏类型
*/
DataMaskingType type() default DataMaskingType.CUSTOM;
/**
* 脱敏开始位置(包含)
*/
int start() default 0;
/**
* 脱敏结束位置(不包含)
*/
int end() default 0;
}
需要注意的是:当DataMaskingType为 CUSTOM 时,才需要填写 start 和 end ,且这两个参数才会生效,且 start 中是包含当前下标的字符的,而 end 不包含当前下标的字符。
编写自定义序列化类
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 valu