- 定义一个枚举类,用于指定不同的脱敏类型,如手机号、身份证
/**
* desc定义一个枚举类,用于指定不同的脱敏类型,比如手机号、身份证号等
*
* @author wcl
*/
public enum SensitiveDataType {
MOBILE,
ID_CARD,
EMAIL,
ADDRESS
}
- 创建一个自定义注解,用于标记需要脱敏的字段
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* desc 创建一个自定义注解,用于标记需要脱敏的字段
*
* @author date
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveData {
SensitiveDataType type();
}
- 创建一个切面类,用于对返回值进行脱敏处理
/**
* @Description: 创建一个切面类,用于对返回值进行脱敏处理
* @author: wcl
* @date: 2025-02-14 13:25
*/
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
/**
* desc 定义脱敏切面
* @author wcl
* @date 2025/2/14 14:37
**/
@Aspect
@Component
public class DesensitizeAspect {
@Around("execution(* com.esop.resurge.dataetlsystem.controller..*(..))")
public Object desensitize(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed(); // 执行原有方法
if (result == null) {
return null;
}
if (result instanceof Collection<?>) { // 处理集合类型返回值
Collection<?> collection = (Collection<?>) result;
Collection<Object> desensitizedCollection = new ArrayList<>(collection.size());
for (Object item : collection) {
try {
desensitizedCollection.add(desensitizeObject(item));
} catch (Exception e) {
// 记录日志或采取其他措施处理异常
desensitizedCollection.add(item); // 或者可以选择跳过该元素
}
}
return desensitizedCollection;
} else if (result.getClass().isArray()) { // 处理数组类型返回值
Object[] array = (Object[]) result;
Object[] desensitizedArray = new Object[array.length];
for (int i = 0; i < array.length; i++) {
try {
desensitizedArray[i] = desensitizeObject(array[i]);
} catch (Exception e) {
// 记录日志或采取其他措施处理异常
desensitizedArray[i] = array[i]; // 或者可以选择跳过该元素
}
}
return desensitizedArray;
} else { // 处理单一对象返回值
try {
return desensitizeObject(result);
} catch (Exception e) {
// 记录日志或采取其他措施处理异常
return result; // 或者可以选择抛出异常
}
}
}
private Object desensitizeObject(Object obj) {
if (obj != null) {
Class<?> clazz = obj.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(SensitiveData.class)) {
// 获取字段的注解
SensitiveData annotation = field.getAnnotation(SensitiveData.class);
SensitiveDataType type = annotation.type();
field.setAccessible(true); // 设置私有字段可访问
try {
// 进行脱敏处理,例如替换为星号等
field.set(obj, setSensitiveData(type, field.get(obj))); // 示例代码,实际应实现脱敏逻辑
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
return obj;
}
private Object setSensitiveData(SensitiveDataType type, Object obj) {
if (obj == null) {
return null;
}
if(type == null){
return obj;
}
String value = String.valueOf(obj);
switch (type) {
case MOBILE:
obj=maskMobile(value);
break;
case ID_CARD:
obj=maskIdCard(value);
break;
case EMAIL:
obj=maskEmail(value);
break;
case ADDRESS:
obj=maskAddress(value);
break;
default:
break;
}
return obj;
}
private String maskMobile(String mobile) {
if (mobile == null || mobile.length() != 11) {
return mobile;
}
return mobile.substring(0, 3) + "****" + mobile.substring(7);
}
private String maskIdCard(String idCard) {
if (idCard == null || idCard.length() != 18) {
return idCard;
}
return idCard.substring(0, 6) + "********" + idCard.substring(14);
}
private String maskEmail(String email) {
if (email == null) {
return email;
}
int atIndex = email.indexOf('@');
if (atIndex == -1) {
return email;
}
if (atIndex < 2) {
return "****"+email.substring(atIndex);
}
StringBuffer sb=new StringBuffer("");
String prefix = email.substring(0, 1);
String suffix = email.substring(atIndex-1);
String midStr = email.substring(1,atIndex-1);
if(midStr!=null && midStr.length()>0){
for(int i=0;i<midStr.length();i++){
sb.append("*");
}
}else{
sb.append("*");
}
return prefix + sb + suffix;
}
private String maskAddress(String address) {
if (address == null || address.length() < 4) {
return address;
}
return address.substring(0, 2) + "****" + address.substring(address.length() - 2);
}
}
- 创建数据实体类,用于测试敏感数据脱敏
/**
* @Description: 创建数据实体类,用于测试敏感数据脱敏
* @author: wcl
* @date: 2025-02-14 13:04
*/
public class User {
private String name;
@SensitiveData(type = SensitiveDataType.MOBILE)
private String mobile;
@SensitiveData(type = SensitiveDataType.ID_CARD)
private String idCard;
@SensitiveData(type = SensitiveDataType.EMAIL)
private String email;
@SensitiveData(type = SensitiveDataType.ADDRESS)
private String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
- 创建接口,测试敏感数据
import com.esop.resurge.dataetlsystem.config.sensitive.User;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @Description: 创建接口,测试敏感数据
* @author: wcl
* @date: 2025-02-14 13:06
*/
@Api(value = "test", tags = {"test"})
@RequestMapping("/test")
@RestController
public class UserController {
@ApiOperation("test")
@GetMapping("/user")
public List<User> getUser() {
User user = new User();
user.setName("张三");
user.setMobile("13800138000");
user.setIdCard("11010519491231002X");
user.setEmail("[email protected]");
user.setAddress("北京市海淀区");
User user2 = new User();
user2.setName("张三2");
user2.setMobile("18911112220");
user2.setIdCard("11010519891231002X");
user2.setEmail("[email protected]");
user2.setAddress("北京市海淀区2");
List<User> list=new ArrayList<>(2);
list.add(user);
list.add(user2);
return list;
}
}
- 调用接口/test/user,查看接口返回,如下图,返回数据已脱敏
