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

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

 


以下是根据别的文章修改或者直接拿过来用的代码
脱敏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. Java并发编程读书笔记(一)

    ----------------------------------------------<Java并发编程实战>读书笔记-------------------------------- ...

  2. 在html页面添加一个隐藏域,并渲染一个需要保存的数值,在js中需要再获取,而不影响页面结构

    <div style="display:none">可以将需要保存的数值放在文本内容中,也可以放在标签的属性当中, 如果放在文本内容中,注意换行后 \n 的存在< ...

  3. jzoj5805

    #include<bits/stdc++.h> using namespace std; int x,n,pp,ct[10000]; long double f[210][(1<&l ...

  4. [Other] 应用下载网站的APK/IPA等常见MIME设置

    类型 扩展名 mime 错误做法 安卓安装包 .apk application/vnd.android.package-archive application/vnd.android 苹果安装包 .i ...

  5. jvm内存结构(一)(结构总览)

    jvm内存结构:<Java虚拟机原理图解>3.JVM运行时数据区 程序计数器: ,是执行的字节码的行号指示器,记录的是正在执行的虚拟机字节码指令的地址. ,每个线程都有独立计数器,互不干扰 ...

  6. 切割数组 - 将一个数组拆分成多个长度为n的数组

    有时候接口返回的数据很长,而前端显示需要分组显示这些数据,这个时候就需要将数组拆分: datas = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]; var arrLen ...

  7. 【12】JMicro微服务-Zookeeper

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 往下看前,建议完成前面1到11小节 1. CuratorFramework支持 JMicro目前基于Zookeeper实现统 ...

  8. 【learning】 单调队列与单调栈用法详解

    1.单调栈 单调栈是指一个栈内部的元素具有严格单调性的一种数据结构,分为单调递增栈和单调递减栈. 其具有以下两个性质: 1,满足栈底到栈顶的元素具有严格单调性. 2,满足栈的先进后出特性,越靠近栈顶的 ...

  9. Nginx Web服务(一)

    一.Nginx原理介绍 1.1:什么是Nginx Nginx是一个开源的,支持高性能.高并发的WWW服务和代理服务软件 1.2:Nginx的功能特点及应用场合 ① 支持高并发:能支持几万并发连接,特别 ...

  10. ubuntu 镜像站部署

    定时任务 #mirror web */5 * * * * cd /mirror && git pull #mysql mirror 0 */3 * * * rsync -av --de ...