所谓数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供测试使用,如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。
此随笔是根据其他文章修改后符合自己项目使用的数据脱敏!!
以下是根据别的文章修改或者直接拿过来用的代码
脱敏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对象就可以进行脱敏了