一、创建一个脱敏工具类
package com.example.utils;
import org.apache.commons.lang3.StringUtils;
/**
* 敏感信息脱敏工具类
*
* @Description
* @Author WL
* @Date 2023/7/20
**/
public class MaskUtil {
/**
* 手机号脱敏
* @param phone
* @return
*/
public final static String maskPhone(String phone){
if(phone==null || phone.length()!=11) {
return phone;
}
return StringUtils.join(phone.substring(0,3)+"******"+phone.substring(9));
}
/**
* 身份证号脱敏
* @param id
* @return
*/
public final static String maskIdCard(String id){
if(id==null || id.length()!=18) {
return id;
}
return StringUtils.join(id.substring(0,6)+"****");
}
/**
*中文姓名脱敏
* @param fullName
* @return
*/
public final static String chineseName(String fullName) {
if(StringUtils.isBlank(fullName)) {
return fullName;
}
String name = StringUtils.left(fullName, 1);
return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
}
/**
*家庭住址脱敏
* @param address
* @param sensitiveSize 敏感信息长度
* @return
*/
public final static String address(String address, int sensitiveSize) {
if(StringUtils.isBlank(address)) {
return address;
}
int length = StringUtils.length(address);
return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length - sensitiveSize+4, "*");
}
/**
*邮箱脱敏
* @param email
* @return
*/
public final static String email(String email) {
if (StringUtils.isBlank(email)) {
return email;
}
int index = StringUtils.indexOf(email, "@");
if(index <= 1) {
return email;
} else {
return StringUtils.rightPad(StringUtils.left(email, 1), index, "*").concat(StringUtils.mid(email, index, StringUtils.length(email)));
}
}
/**
*银行卡号脱敏
* @param cardNum
* @return
*/
public final static String bankCard(String cardNum) {
if(StringUtils.isBlank(cardNum)) {
return cardNum;
}
return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******"));
}
/**
*固定电话脱敏
* @param num
* @return
*/
public final static String fixedPhone(String num) {
if(StringUtils.isBlank(num)) {
return num;
}
return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");
}
/**
* 【中国车牌】车牌中间用*代替 eg1:null -》 "" eg1:"" -》 "" eg3:苏D40000 -》 苏D4***0 eg4:陕A12345D -》 陕A1****D eg5:京A123 -》 京A123 如果是错误的车牌,不处理
*
* @param carLicense 完整的车牌号
* @return 脱敏后的车牌号
*/
public static String carLicense(String carLicense) {
if (StringUtils.isBlank(carLicense)) {
return "";
} else {
if (carLicense.length() == 7) {
carLicense = StringUtils.join(carLicense.substring(0,3)+"***"+carLicense.substring(6));
} else if (carLicense.length() == 8) {
carLicense = StringUtils.join(carLicense.substring(0,3)+"***"+carLicense.substring(7));
}
return carLicense;
}
}
}
二、编写自定义注解
package com.example.config.interfaces;
import java.lang.annotation.*;
/**
* 脱敏信息注解
*
* @Description
* @Author WL
* @Date 2023/7/20
**/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SensitiveField {
SensitiveTypeEnum value() default SensitiveTypeEnum.IDCARD;
enum SensitiveTypeEnum {
IDCARD,
PHONE,
NAME,
ADDRESS,
BANK,
CARLICENSE,
}
}
三、脱敏拦截
package com.example.config.interfaces;
import com.example.utils.MaskUtil;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
/**
*
*
* @Description
* @Author WL
* @Date 2023/7/20
**/
@Aspect
@Configuration
public class SensitiveAspect {
public static final String ACCESS_EXECUTION = "execution(* com.example..*.*(..))";
/**
* 注解脱敏处理
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around(ACCESS_EXECUTION)
public Object sensitiveClass(ProceedingJoinPoint joinPoint) throws Throwable {
return sensitiveFormat(joinPoint);
}
/**
* 插拔式注解统一拦截器。@SensitiveField
*
* @param joinPoint
* @return
* @throws Throwable
*/
public Object sensitiveFormat(ProceedingJoinPoint joinPoint) throws Throwable {
Object obj = joinPoint.proceed();
if (obj == null || isPrimitive(obj.getClass())) {
return obj;
}
for (Field field : obj.getClass().getDeclaredFields()) {
ReflectionUtils.makeAccessible(field);
SensitiveField sensitiveField = field.getAnnotation(SensitiveField.class);
if (sensitiveField != null) {
Object value = field.get(obj);
switch (sensitiveField.value()) {
case IDCARD:
String idCard = MaskUtil.maskIdCard((String) value);
ReflectionUtils.setField(field, obj, idCard);
break;
case PHONE:
String phone = MaskUtil.maskPhone((String) value);
ReflectionUtils.setField(field, obj, phone);
break;
case NAME:
String name = MaskUtil.chineseName((String) value);
ReflectionUtils.setField(field, obj, name);
break;
case ADDRESS:
//TODO
String address = MaskUtil.address((String) value, StringUtils.length((String) value));
ReflectionUtils.setField(field, obj, address);
break;
case BANK:
//TODO
String bankCard = MaskUtil.bankCard((String) value);
ReflectionUtils.setField(field, obj, bankCard);
break;
case CARLICENSE:
//TODO
String carLicense = MaskUtil.carLicense((String) value);
ReflectionUtils.setField(field, obj, carLicense);
break;
default:
break;
}
}
}
return obj;
}
/**
* 基本数据类型和String类型判断
*
* @param clz
* @return
*/
private boolean isPrimitive(Class<?> clz) {
try {
if (String.class.isAssignableFrom(clz) || clz.isPrimitive()) {
return true;
} else {
return ((Class) clz.getField("TYPE").get(null)).isPrimitive();
}
} catch (Exception e) {
return false;
}
}
}
四、编写一个对象使用注解
package com.example.model;
import com.example.config.interfaces.SensitiveField;
import lombok.Data;
/**
* TODO
*
* @Description
* @Author WL
* @Date 2023/7/20
**/
@Data
public class MskDto {
@SensitiveField(SensitiveField.SensitiveTypeEnum.IDCARD)
private String idCard;
@SensitiveField(SensitiveField.SensitiveTypeEnum.NAME)
private String complainantName;
@SensitiveField(SensitiveField.SensitiveTypeEnum.PHONE)
private String respondentPhone;
@SensitiveField(SensitiveField.SensitiveTypeEnum.BANK)
private String bankCard;
@SensitiveField(SensitiveField.SensitiveTypeEnum.CARLICENSE)
private String carLicense;
}
五、验证Controller
package com.example.controller;
import com.example.model.MskDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
/**
* TODO
*
* @Description
* @Author WL
* @Date 2023/7/20
**/
@Slf4j
@RequestMapping("/mas")
@RestController
public class MasController {
@PostMapping("/test")
public MskDto sayHelloMqTest(@RequestBody MskDto request) throws Exception{
log.info("idcard: {}", request.getIdCard().toString());
log.info("name: {}", request.getComplainantName());
log.info("phone: {}", request.getRespondentPhone());
return request;
}
}
六、验证结果
![](https://i-blog.csdnimg.cn/blog_migrate/b88756b909c74ea26f8519dea4df521e.jpeg)