欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java 数据脱敏

程序员文章站 2022-04-14 11:05:23
所谓数据脱敏是指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。在涉及客户安全数据或者一些商业性敏感数据的情况下,在不违反系统规则条件下,对真实数据进行改造并提供测试使用,如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。 此随笔是根据其他文章修改后符合自己项目使用 ......

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

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

 




以下是根据别的文章修改或者直接拿过来用的代码
脱敏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.*error)
     *
     * @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对象、page、limit和传回前端的vo的class对象就可以进行脱敏了