所谓数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供测试使用,如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。

  此随笔是根据其他文章修改后符合自己项目使用的数据脱敏!!

 


以下是根据别的文章修改或者直接拿过来用的代码
脱敏enum
/**
* @Title: SensitiveTypeEnum
* @Description:
*/
public enum SensitiveTypeEnum {
/**
* 中文名
*/
CHINESE_NAME,
/**
* 身份证号
*/
ID_CARD,
/**
* 座机号
*/
FIXED_PHONE,
/**
* 手机号
*/
MOBILE_PHONE,
/**
* 地址
*/
ADDRESS,
/**
* 电子邮件
*/
EMAIL,
/**
* 银行卡
*/
BANK_CARD,
/**
* 密码
*/
PASSWORD;
}

自定义annotation

/**
* @Title: Desensitized
* @Description: 敏感信息注解标记
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Desensitized { /*脱敏类型(规则)*/
SensitiveTypeEnum type(); /*判断注解是否生效的方法*/
String isEffictiveMethod() default ""; }
utils工具类
public class ObjectUtils {
/**
* 用序列化-反序列化方式实现深克隆
* 缺点:1、被拷贝的对象必须要实现序列化
*
* @param obj
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T deepCloneObject(T obj) {
T t = (T) new Object();
try {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(obj);
out.close();
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
t = (T) in.readObject();
in.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return t;
} /**
* 用序列化-反序列化的方式实现深克隆
* 缺点:1、当实体中存在接口类型的参数,并且这个接口指向的实例为枚举类型时,会报错"com.alibaba.fastjson.JSONException: syntax error, expect {, actual string, pos 171, fieldName iLimitKey"
*
* @param objSource
* @return
*/
public static Object deepCloneByFastJson(Object objSource) {
String tempJson = JSON.toJSONString(objSource);
Object clone = JSON.parseObject(tempJson, objSource.getClass());
return clone;
} /**
* 深度克隆对象
*
* @throws IllegalAccessException
* @throws InstantiationException
*/
public static Object deepClone(Object objSource) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
if (null == objSource) return null;
//是否jdk类型、基础类型、枚举类型
if (isJDKType(objSource.getClass())
|| objSource.getClass().isPrimitive()
|| objSource instanceof Enum<?>) {
if ("java.lang.String".equals(objSource.getClass().getName())) {//目前只支持String类型深复制
return new String((String) objSource);
} else {
return objSource;
}
}
// 获取源对象类型
Class<?> clazz = objSource.getClass();
Object objDes = clazz.newInstance();
// 获得源对象所有属性
Field[] fields = getAllFields(objSource);
// 循环遍历字段,获取字段对应的属性值
for (Field field : fields) {
field.setAccessible(true);
if (null == field) continue;
Object value = field.get(objSource);
if (null == value) continue;
Class<?> type = value.getClass();
if (isStaticFinal(field)) {
continue;
}
try { //遍历集合属性
if (type.isArray()) {//对数组类型的字段进行递归过滤
int len = Array.getLength(value);
if (len < 1) continue;
Class<?> c = value.getClass().getComponentType();
Array newArray = (Array) Array.newInstance(c, len);
for (int i = 0; i < len; i++) {
Object arrayObject = Array.get(value, i);
Array.set(newArray, i, deepClone(arrayObject));
}
} else if (value instanceof Collection<?>) {
Collection newCollection = (Collection) value.getClass().newInstance();
Collection<?> c = (Collection<?>) value;
Iterator<?> it = c.iterator();
while (it.hasNext()) {
Object collectionObj = it.next();
newCollection.add(deepClone(collectionObj));
}
field.set(objDes, newCollection);
continue;
} else if (value instanceof Map<?, ?>) {
Map newMap = (Map) value.getClass().newInstance();
Map<?, ?> m = (Map<?, ?>) value;
Set<?> set = m.entrySet();
for (Object o : set) {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
Object mapVal = entry.getValue();
newMap.put(entry.getKey(), deepClone(mapVal));
}
field.set(objDes, newMap);
continue;
} //是否jdk类型或基础类型
if (isJDKType(field.get(objSource).getClass())
|| field.getClass().isPrimitive()
|| isStaticType(field)
|| value instanceof Enum<?>) {
if ("java.lang.String".equals(value.getClass().getName())) {//目前只支持String类型深复制
field.set(objDes, new String((String) value));
} else {
field.set(objDes, field.get(objSource));
}
continue;
} //是否枚举
if (value.getClass().isEnum()) {
field.set(objDes, field.get(objSource));
continue;
} //是否自定义类
if (isUserDefinedType(value.getClass())) {
field.set(objDes, deepClone(value));
continue;
} } catch (Exception e) {
e.printStackTrace();
}
}
return objDes;
} /**
* 是否静态变量
*
* @param field
* @return
*/
private static boolean isStaticType(Field field) {
return field.getModifiers() == 8 ? true : false;
} private static boolean isStaticFinal(Field field) {
return Modifier.isFinal(field.getModifiers()) && Modifier.isStatic(field.getModifiers());
} /**
* 是否jdk类型变量
*
* @param clazz
* @return
* @throws IllegalAccessException
*/
private static boolean isJDKType(Class clazz) throws IllegalAccessException {
//Class clazz = field.get(objSource).getClass();
return StringUtils.startsWith(clazz.getPackage().getName(), "javax.")
|| StringUtils.startsWith(clazz.getPackage().getName(), "java.")
|| StringUtils.startsWith(clazz.getName(), "javax.")
|| StringUtils.startsWith(clazz.getName(), "java.");
} /**
* 是否用户自定义类型
*
* @param clazz
* @return
*/
private static boolean isUserDefinedType(Class<?> clazz) {
return
clazz.getPackage() != null
&& !StringUtils.startsWith(clazz.getPackage().getName(), "javax.")
&& !StringUtils.startsWith(clazz.getPackage().getName(), "java.")
&& !StringUtils.startsWith(clazz.getName(), "javax.")
&& !StringUtils.startsWith(clazz.getName(), "java.");
} /**
* 获取包括父类所有的属性
*
* @param objSource
* @return
*/
public static Field[] getAllFields(Object objSource) {
/*获得当前类的所有属性(private、protected、public)*/
List<Field> fieldList = new ArrayList<Field>();
Class tempClass = objSource.getClass();
while (tempClass != null && !tempClass.getName().toLowerCase().equals("java.lang.object")) {//当父类为null的时候说明到达了最上层的父类(Object类).
fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
tempClass = tempClass.getSuperclass(); //得到父类,然后赋给自己
}
Field[] fields = new Field[fieldList.size()];
fieldList.toArray(fields);
return fields;
} /**
* 深度克隆对象
*
* @throws IllegalAccessException
* @throws InstantiationException
*/
@Deprecated
public static Object copy(Object objSource) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { if (null == objSource) return null;
// 获取源对象类型
Class<?> clazz = objSource.getClass();
Object objDes = clazz.newInstance();
// 获得源对象所有属性
Field[] fields = getAllFields(objSource);
// 循环遍历字段,获取字段对应的属性值
for (Field field : fields) {
field.setAccessible(true);
// 如果该字段是 static + final 修饰
if (field.getModifiers() >= 24) {
continue;
}
try {
// 设置字段可见,即可用get方法获取属性值。
field.set(objDes, field.get(objSource));
} catch (Exception e) {
e.printStackTrace();
}
}
return objDes;
}
}
/**
* @Title: DesensitizedUtils
* @Description:脱敏工具
*/
public class DesensitizedUtils { /**
* 获取脱敏json串(递归引用会导致java.lang.StackOverflowError)
*
* @param javaBean
* @return
*/
public static Object getJson(Object javaBean) {
String json = null;
if (null != javaBean) {
try {
if (javaBean.getClass().isInterface()) return json;
/* 定义一个计数器,用于避免重复循环自定义对象类型的字段 */
Set<Integer> referenceCounter = new HashSet<Integer>(); /* 对实体进行脱敏操作 */
DesensitizedUtils.replace(ObjectUtils.getAllFields(javaBean), javaBean, referenceCounter); /* 清空计数器 */
referenceCounter.clear();
referenceCounter = null;
} catch (Throwable e) {
e.printStackTrace();
}
}
return javaBean;
} /**
* 对需要脱敏的字段进行转化
*
* @param fields
* @param javaBean
* @param referenceCounter
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private static void replace(Field[] fields, Object javaBean, Set<Integer> referenceCounter) throws IllegalArgumentException, IllegalAccessException {
if (null != fields && fields.length > 0) {
for (Field field : fields) {
field.setAccessible(true);
if (null != field && null != javaBean) {
Object value = field.get(javaBean);
if (null != value) {
Class<?> type = value.getClass();
//处理子属性,包括集合中的
if (type.isArray()) {//对数组类型的字段进行递归过滤
int len = Array.getLength(value);
for (int i = 0; i < len; i++) {
Object arrayObject = Array.get(value, i);
if (isNotGeneralType(arrayObject.getClass(), arrayObject, referenceCounter)) {
replace(ObjectUtils.getAllFields(arrayObject), arrayObject, referenceCounter);
}
}
} else if (value instanceof Collection<?>) {//对集合类型的字段进行递归过滤
Collection<?> c = (Collection<?>) value;
Iterator<?> it = c.iterator();
while (it.hasNext()) {// TODO: 待优化
Object collectionObj = it.next();
if (isNotGeneralType(collectionObj.getClass(), collectionObj, referenceCounter)) {
replace(ObjectUtils.getAllFields(collectionObj), collectionObj, referenceCounter);
}
}
} else if (value instanceof Map<?, ?>) {//对Map类型的字段进行递归过滤
Map<?, ?> m = (Map<?, ?>) value;
Set<?> set = m.entrySet();
for (Object o : set) {
Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
Object mapVal = entry.getValue();
if (isNotGeneralType(mapVal.getClass(), mapVal, referenceCounter)) {
replace(ObjectUtils.getAllFields(mapVal), mapVal, referenceCounter);
}
}
} else if (value instanceof Enum<?>) {
continue;
} /*除基础类型、jdk类型的字段之外,对其他类型的字段进行递归过滤*/
else {
if (!type.isPrimitive()
&& type.getPackage() != null
&& !StringUtils.startsWith(type.getPackage().getName(), "javax.")
&& !StringUtils.startsWith(type.getPackage().getName(), "java.")
&& !StringUtils.startsWith(field.getType().getName(), "javax.")
&& !StringUtils.startsWith(field.getName(), "java.")
&& referenceCounter.add(value.hashCode())) {
replace(ObjectUtils.getAllFields(value), value, referenceCounter);
}
}
}
//脱敏操作
setNewValueForField(javaBean, field, value); }
}
}
} /**
* 排除基础类型、jdk类型、枚举类型的字段
*
* @param clazz
* @param value
* @param referenceCounter
* @return
*/
private static boolean isNotGeneralType(Class<?> clazz, Object value, Set<Integer> referenceCounter) {
return !clazz.isPrimitive()
&& clazz.getPackage() != null
&& !clazz.isEnum()
&& !StringUtils.startsWith(clazz.getPackage().getName(), "javax.")
&& !StringUtils.startsWith(clazz.getPackage().getName(), "java.")
&& !StringUtils.startsWith(clazz.getName(), "javax.")
&& !StringUtils.startsWith(clazz.getName(), "java.")
&& referenceCounter.add(value.hashCode());
} /**
* 脱敏操作(按照规则转化需要脱敏的字段并设置新值)
* 目前只支持String类型的字段,如需要其他类型如BigDecimal、Date等类型,可以添加
*
* @param javaBean
* @param field
* @param value
* @throws IllegalAccessException
*/
public static void setNewValueForField(Object javaBean, Field field, Object value) throws IllegalAccessException { //处理自身的属性
Desensitized annotation = field.getAnnotation(Desensitized.class);
if (field.getType().equals(String.class) && null != annotation && executeIsEffictiveMethod(javaBean, annotation)) {
String valueStr = (String) value;
if (StringUtils.isNotBlank(valueStr)) {
switch (annotation.type()) {
case CHINESE_NAME: {
field.set(javaBean, DesensitizedUtils.chineseName(valueStr));
break;
}
case ID_CARD: {
field.set(javaBean, DesensitizedUtils.idCardNum(valueStr));
break;
}
case FIXED_PHONE: {
field.set(javaBean, DesensitizedUtils.fixedPhone(valueStr)); break;
}
case MOBILE_PHONE: {
field.set(javaBean, DesensitizedUtils.mobilePhone(valueStr));
break;
}
case ADDRESS: {
field.set(javaBean, DesensitizedUtils.address(valueStr, 8));
break;
}
case EMAIL: {
field.set(javaBean, DesensitizedUtils.email(valueStr));
break;
}
case BANK_CARD: {
field.set(javaBean, DesensitizedUtils.bankCard(valueStr));
break;
}
case PASSWORD: {
field.set(javaBean, DesensitizedUtils.password(valueStr));
break;
}
}
}
}
} /**
* 执行某个对象中指定的方法
*
* @param javaBean 对象
* @param desensitized
* @return
*/
private static boolean executeIsEffictiveMethod(Object javaBean, Desensitized desensitized) {
boolean isAnnotationEffictive = true;//注解默认生效
if (desensitized != null) {
String isEffictiveMethod = desensitized.isEffictiveMethod();
if (isNotEmpty(isEffictiveMethod)) {
try {
Method method = javaBean.getClass().getMethod(isEffictiveMethod);
method.setAccessible(true);
isAnnotationEffictive = (Boolean) method.invoke(javaBean);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
return isAnnotationEffictive;
} private static boolean isNotEmpty(String str) {
return str != null && !"".equals(str);
} private static boolean isEmpty(String str) {
return !isNotEmpty(str);
} /**
* 【中文姓名】只显示第一个汉字,其他隐藏为2个星号,比如:李**
*
* @param fullName
* @return
*/
public static String chineseName(String fullName) {
if (StringUtils.isBlank(fullName)) {
return "";
}
String name = StringUtils.left(fullName, 1);
return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
} /**
* 【身份证号】显示最后四位,其他隐藏。共计18位或者15位,比如:*************1234
*
* @param id
* @return
*/
public static String idCardNum(String id) {
if (StringUtils.isBlank(id)) {
return "";
}
String num = StringUtils.right(id, 4);
return StringUtils.leftPad(num, StringUtils.length(id), "*");
} /**
* 【固定电话 后四位,其他隐藏,比如1234
*
* @param num
* @return
*/
public static String fixedPhone(String num) {
if (StringUtils.isBlank(num)) {
return "";
}
return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");
} /**
* 【手机号码】前三位,后四位,其他隐藏,比如135****6810
*
* @param num
* @return
*/
public static String mobilePhone(String num) {
if (StringUtils.isBlank(num)) {
return "";
}
return StringUtils.left(num, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*"), "***"));
} /**
* 【地址】只显示到地区,不显示详细地址,比如:北京市海淀区****
*
* @param address
* @param sensitiveSize 敏感信息长度
* @return
*/
public static String address(String address, int sensitiveSize) {
if (StringUtils.isBlank(address)) {
return "";
}
int length = StringUtils.length(address);
return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length, "*");
} /**
* 【电子邮箱 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示,比如:d**@126.com>
*
* @param email
* @return
*/
public static String email(String email) {
if (StringUtils.isBlank(email)) {
return "";
}
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)));
} /**
* 【银行卡号】前六位,后四位,其他用星号隐藏每位1个星号,比如:6222600**********1234>
*
* @param cardNum
* @return
*/
public static String bankCard(String cardNum) {
if (StringUtils.isBlank(cardNum)) {
return "";
}
return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******"));
} /**
* 【密码】密码的全部字符都用*代替,比如:******
*
* @param password
* @return
*/
public static String password(String password) {
if (StringUtils.isBlank(password)) {
return "";
}
String pwd = StringUtils.left(password, 0);
return StringUtils.rightPad(pwd, StringUtils.length(password), "*");
} /**
* 遍历page对数据脱敏
* @param pageContent
* @param page
* @param size
* @return
*/
public static <T> Page desensitizedPage(Page<T> pageContent, int page, int size,Class tClass) {
//获取page的内容
List<T> content = pageContent.getContent();
if (content == null || content.size() <= 0) {
return pageContent;
}
//数据脱敏
List list = desensitizedList(content,tClass);
return new PageImpl(list, new PageRequest(page, size), pageContent.getTotalElements());
} /**
* 遍历List脱敏数据
* @param content
* @return
*/
public static <T> List desensitizedList(List<T> content,Class tClass){
if (content == null || content.size() <= 0) {
return content;
}
List list = new ArrayList<>();
for (T t : content) {
list.add(desensitizedObject(t,tClass));
}
return list;
}
/**
* 对象脱敏
* @param content
* @return
*/
public static <T> Object desensitizedObject(T content,Class tClass){
if(content != null){
try {
Object o = tClass.newInstance();
BeanCopyUtil.copyPropertiesIgnoreNull(content,o);
return getJson(o);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return null;
}
}

最后面的几个方法是我根据泛型和反射创建的对page、list 、实体的脱敏方法。

 

 以下是我的代码

  后端实体

import org.hibernate.annotations.GenericGenerator;

import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.util.Date; /**
* 黑名单
* @ClassName: BlackList
* @author: guoyuzai
* @version 0.98
*/
@Entity
@Table(name = "black_list", catalog = "zhsupervision")
public class BlackList { /** 主键ID,UUID **/
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid")
@Column(nullable = false, length = 32)
private String id; /**
* 姓名
*/ private String name; /**
* 身份证
*/
private String idCard; /**
* 处罚日期
*/ @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String punishDate; /**
* 处罚事由
*/
private String punishCause; /**
* 逻辑删除标识符 0:正常 1:删除不显示
*/
private String delFlag; /**
* 状态
*/
private String status; /**
* 备注
*/
private String remark; /**
* A新增 U更新D删除
*/
private String identifier; /**
* 创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; /**
* 证件类型
*/
private String cardType; /**
* 创建人
*/
private String createUser; /**
* 修改人
*/
private String updateUser; /**
* 更新时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateDate; /**
* 附件
*/
private String attachement; public String getAttachement() {
return attachement;
} public void setAttachement(String attachement) {
this.attachement = attachement;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getPunishDate() {
return punishDate;
} public void setPunishDate(String punishDate) {
this.punishDate = punishDate;
} public String getPunishCause() {
return punishCause;
} public void setPunishCause(String punishCause) {
this.punishCause = punishCause;
} public String getDelFlag() {
return delFlag;
} public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
} public String getStatus() {
return status;
} public void setStatus(String status) {
this.status = status;
} public String getRemark() {
return remark;
} public void setRemark(String remark) {
this.remark = remark;
} public String getIdentifier() {
return identifier;
} public void setIdentifier(String identifier) {
this.identifier = identifier;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} public String getCardType() {
return cardType;
} public void setCardType(String cardType) {
this.cardType = cardType;
} public String getCreateUser() {
return createUser;
} public void setCreateUser(String createUser) {
this.createUser = createUser;
} public String getUpdateUser() {
return updateUser;
} public void setUpdateUser(String updateUser) {
this.updateUser = updateUser;
} public Date getUpdateDate() {
return updateDate;
} public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
} public String getIdCard() {
return idCard;
} public void setIdCard(String idCard) {
this.idCard = idCard;
} @Override
public String toString() {
return "BlackList{" +
"name='" + name + '\'' + ", IdCard='" + idCard + '\'' +
", punishDate='" + punishDate + '\'' +
", orgName='" + orgName + '\'' +
", punishCause='" + punishCause + '\'' +
", delFlag='" + delFlag + '\'' +
", status='" + status + '\'' +
", remark='" + remark + '\'' +
", identifier='" + identifier + '\'' +
", createTime=" + createTime +
", cardType='" + cardType + '\'' +
", createUser='" + createUser + '\'' +
", updateUser='" + updateUser + '\'' +
", updateDate=" + updateDate +
", id='" + id + '\'' +
'}';
}
}

 返回结果给前端的VO

import com.honebay.spv.core.annotation.Desensitized;
import com.honebay.spv.core.enums.SensitiveTypeEnum;
import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; public class BlackListVO {
private String id; /**
* 姓名
*/
private String name; /**
* 身份证
*/
@Desensitized(type = SensitiveTypeEnum.ID_CARD)
private String idCard; /**
* 处罚日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String punishDate; /**
* 处罚事由
*/
private String punishCause; /**
* 逻辑删除标识符 0:正常 1:删除不显示
*/
private String delFlag; /**
* 状态
*/
private String status; /**
* 备注
*/
private String remark; /**
* A新增 U更新D删除
*/
private String identifier; /**
* 创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; /**
* 证件类型
*/
private String cardType; /**
* 创建人
*/
private String createUser; /**
* 修改人
*/
private String updateUser; /**
* 更新时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateDate; /**
* 附件
*/
private String attachement; public String getAttachement() {
return attachement;
} public void setAttachement(String attachement) {
this.attachement = attachement;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getPunishDate() {
return punishDate;
} public void setPunishDate(String punishDate) {
this.punishDate = punishDate;
} public String getPunishCause() {
return punishCause;
} public void setPunishCause(String punishCause) {
this.punishCause = punishCause;
} public String getDelFlag() {
return delFlag;
} public void setDelFlag(String delFlag) {
this.delFlag = delFlag;
} public String getStatus() {
return status;
} public void setStatus(String status) {
this.status = status;
} public String getRemark() {
return remark;
} public void setRemark(String remark) {
this.remark = remark;
} public String getIdentifier() {
return identifier;
} public void setIdentifier(String identifier) {
this.identifier = identifier;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} public String getCardType() {
return cardType;
} public void setCardType(String cardType) {
this.cardType = cardType;
} public String getCreateUser() {
return createUser;
} public void setCreateUser(String createUser) {
this.createUser = createUser;
} public String getUpdateUser() {
return updateUser;
} public void setUpdateUser(String updateUser) {
this.updateUser = updateUser;
} public Date getUpdateDate() {
return updateDate;
} public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
} public String getIdCard() {
return idCard;
} public void setIdCard(String idCard) {
this.idCard = idCard;
}
}

上面的身份证我添加了自定义的注解,在脱敏的时候会找到这个注解然后获取属性的值进行脱敏

Service

import com.honebay.spv.core.service.BaseService;
import com.honebay.spv.org.entity.BlackList;
import com.honebay.spv.org.entity.EmployeesInfor;
import org.springframework.data.domain.Page; import java.util.List; /**
* @author guoyuzai
* @version 0.98
*/
public interface BlackListService extends BaseService<BlackList,String> {
/**
* 获取分页列表
*
* @param page
* @param size
* @return
*/
public Page<BlackList> getBlackListPage(BlackList info, int page, int size); }

 

Impl

@Service
public class BlackListServiceImpl extends BaseServiceImpl<BlackList, String> implements BlackListService {
private final Logger log = LoggerFactory.getLogger(BlackListServiceImpl.class); @SuppressWarnings("unchecked")
@Override
public Page<BlackList> getBlackListPage(BlackList blackList, int page, int size) {
Page<BlackList> result = null;
Specification<BlackList> specialized = new Specification<BlackList>() {
@Override
public Predicate toPredicate(Root<BlackList> root, CriteriaQuery<?> query,
CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<Predicate>(); if(StringUtils.isNotBlank(blackList.getIdCard())){
Predicate idCard = criteriaBuilder.equal(root.get("idCard"), blackList.getIdCard());
predicates.add(idCard);
} if(StringUtils.isNotBlank(blackList.getName())){
Predicate name = criteriaBuilder.equal(root.get("name"), blackList.getName());
predicates.add(name);
} //获取没删除的信息
Predicate flag = criteriaBuilder.equal(root.get("delFlag"), "0");
predicates.add(flag); return criteriaBuilder.and(predicates.toArray(new Predicate[] {}));
} }; /**
* 按照创建时间排序
*/
List<Sort.Order> orderList = new ArrayList<Sort.Order>();
orderList.add(new Sort.Order(Sort.Direction.ASC, "createTime"));
result = blackListRepository.findAll(specialized,new PageRequest(page, size,new Sort(orderList))); return result;
}
}

Repository
public interface BlackListRepository extends BaseRepository<BlackList, String>, JpaSpecificationExecutor {

}

Controller

/**
* 黑名单
* @ClassName: BlackList
* @author: guoyuzai
* @version 0.98
*/
@RestController
public class BlackListController {
@Autowired
private BlackListService blackListService; /**
*
* @Title: infoQueryPortalList
* @Description: 分页查询
* @param: @return
* @return: JsonResponseN
* @throws
*/
@SuppressWarnings("rawtypes")
@RequestMapping(value = "/getBlackListPage")
@ResponseBody
public JsonResponseExt getBlackListPage(BlackList info, @RequestParam("page")String page, @RequestParam("limit") String limit) { Page<BlackList> pageData =blackListService.getBlackListPage(info,Integer.parseInt(page) - 1,Integer.parseInt(limit));
    
     JsonResponseExt je = JsonResponseExt.successPage(DesensitizedUtils.desensitizedPage(pageData,Integer.parseInt(page) - 1,Integer.parseInt(limit),BlackListVO.class));
     return je; 
  }
}
JsonResponseExt je = JsonResponseExt.successPage()这个方法是自己封装给前端的返回对象(这里不提供)
根据工具类的 DesensitizedUtils.desensitizedPage()方法 传入自定义对象、page、list和VO对象的Class对象就可以进行脱敏了
 

java 数据脱敏的更多相关文章

  1. Java 数据脱敏 工具类

    一.项目导入Apache的commons的Jar包. Jar包Maven下载地址:https://mvnrepository.com/artifact/org.apache.commons/commo ...

  2. 如何用java实现数据脱敏

    数据脱敏是什么意思呢? 数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护.在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并 ...

  3. Springboot 配置文件、隐私数据脱敏的最佳实践(原理+源码)

    大家好!我是小富- 这几天公司在排查内部数据账号泄漏,原因是发现某些实习生小可爱居然连带着账号.密码将源码私传到GitHub上,导致核心数据外漏,孩子还是没挨过社会毒打,这种事的后果可大可小. 说起这 ...

  4. 利用Jackson序列化实现数据脱敏

    几天前使用了Jackson对数据的自定义序列化.突发灵感,利用此方法来简单实现接口返回数据脱敏,故写此文记录. 核心思想是利用Jackson的StdSerializer,@JsonSerialize, ...

  5. 数据脱敏 t-closeness介绍与实现

    数据脱敏 t-closeness介绍与实现 本文主要基于t-closeness的首次提出团队Ninghui Li, Tiancheng Li, Suresh Venkatasubramanian发表的 ...

  6. ShardingJdbc-分表;分库;分库分表;读写分离;一主多从+分表;一主多从+分库分表;公共表;数据脱敏;分布式事务

    目录 创建项目 分表 导包 表结构 Yml 分库 Yml Java 分库分表 数据库 Yml 读写分离 数据库 Yml 其他 只请求主库 读写分离判断逻辑代码 一主多从+分表 Yml 一主多从+分库分 ...

  7. 基于Mybatis插件方式实现数据脱敏处理

    一.项目介绍 1.项目背景 有时候我们数据库中存储一些敏感的信息比如手机号.银行卡号,我们希望我们查询出来的的时候对一些敏感信息做一些脱敏处理. 当面项目是基于自定义Mybatis插件方式实现数据脱敏 ...

  8. JSONObject.fromObject(map)(JSON与JAVA数据的转换)

    JSON与JAVA数据的转换(JSON 即 JavaScript Object Natation,它是一种轻量级的数据交换格式,非常适合于服务器与 JavaScript 的交互.) 上一篇文章中有这么 ...

  9. 关于JAVA数据储存

    关于JAVA数据储存: 在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register) 这是最快的存储区,因为它位于不同于其他存储区的地方--处理器内部.但是寄存器的数量极其有限,所以 ...

随机推荐

  1. map函数和reduce函数、filter函数的区别

    ①从参数方面来讲:map()函数: map()包含两个参数,第一个是参数是一个函数,第二个是序列(列表或元组).其中,函数(即map的第一个参数位置的函数)可以接收一个或多个参数.reduce()函数 ...

  2. C#后端接收form-data,创建实体类

    public class Para_list //实体类 { public long ParemeterID { get; set; } public string Name { get; set; ...

  3. SSL学习笔记

    /************************************数据类型***************************************//* Number(数值型),Bool ...

  4. webpack快速入门——打包后如何调试

    在配置devtool时,webpack给我们提供了四种选项. source-map:在一个单独文件中产生一个完整且功能完全的文件.这个文件具有最好的source map,但是它会减慢打包速度: che ...

  5. Python-WSGI协议,mini-web框架

    本次带给大家的是WSGI-mini-web框架, 其中要下载一些网络页面, 大佬们不要见怪. 我所做的mini-web 支持路由, 正则表达式, 添加了log日志功能:解析了url编码可以用 来理解W ...

  6. day 43 mysql 学习 以及pymysql 学习

    前情提要: 本次主要学习sql 的难点, 多表查询以及连接python  一:多表关联 >多表查询的缺点 二:单表的连表查询[自关联查询] 三:子查询 >主查询 >主查询 >主 ...

  7. CentOS7搭建FastDFS V5.11分布式文件系统-第二篇

    1.CentOS7 FastDFS搭建 前面已下载好了要用到的工具集,下面就可以开始安装了: 如果安装过程中出现问题,可以下载我提供的,当前测试可以通过的工具包: 点这里点这里 1.1 安装libfa ...

  8. cobbler koan自动重装系统

    介绍 koan是kickstart-over-a-network的缩写,它是cobbler的客户端帮助程序,koan允许你通过网络提供虚拟机,也允许你重装已经存在的客户端.当运行时,koan会从远端的 ...

  9. 使用git时出现Please make sure you have the correct access rights and the repository exists.问题已解决。

    使用git时,出现Please make sure you have the correct access rights and the repository exists.问题已解决. 今天我在使用 ...

  10. Eclipse启动和手动启动tomcat访问localhost:8080显示404问题总结

    前言:建议对tomcat的文件结构和相关属性有较多了解.本文以eclipse的DynamicWebProject为讲解对象. 目录: eclipse添加tomcat关联注意点 tomcat404问题归 ...