思路 1。在 model层进行处理,直接重写get方法,在写一个getPlain 获取明文方法。(缺点:数据库写入和json序列化传递时使用的都是密文)

  2.利用 日志组件过滤 特定的key,去进行脱敏(缺点:对所有的日志输出全部要正则匹配,非常耗时。)

由1,2的利弊,肯定会选择1,然后考虑一种实现(在model层定义方法,获取它的一个复制类,复制类里面的信息都是脱敏的,日志输出时只输出 复制对象),克服掉1的缺点

1.定义接口类

public interface NoSensitiveObj<T> {

    default T noSensitiveObj(){
return (T) this;
}
}

2.实现类 如果这个类没有敏感信息,只实现 NoSensitiveObj ,不需要实现里面的方法

public class User implements NoSensitiveObj<User>{

    private String name;

    private String phone;

    private String email;

    public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getPhone() {
return phone;
} public void setPhone(String phone) {
this.phone = phone;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} @Override
public User noSensitiveObj() {
User t;
t=new User();
t.setEmail(SensitiveInfoUtils.email(email));
t.setName(SensitiveInfoUtils.chineseName(name));
t.setPhone(SensitiveInfoUtils.mobilePhone(phone));
return t;
} }

3.工具类

public class SensitiveInfoUtils {

    /**
* [中文姓名] 只显示第一个汉字,其他隐藏为2个星号<例子:李**>
*/
public static String chineseName(final String fullName) {
if (StringUtils.isBlank(fullName)) {
return "";
}
final String name = StringUtils.left(fullName, 1);
return StringUtils.rightPad(name, StringUtils.length(fullName), "*");
} /**
* [中文姓名] 只显示第一个汉字,其他隐藏为2个星号<例子:李**>
*/
public static String chineseName(final String familyName, final String givenName) {
if (StringUtils.isBlank(familyName) || StringUtils.isBlank(givenName)) {
return "";
}
return chineseName(familyName + givenName);
} /**
* [身份证号] 显示最后四位,其他隐藏。共计18位或者15位。<例子:*************5762>
*/
public static String idCardNum(final String id) {
if (StringUtils.isBlank(id)) {
return "";
} return StringUtils.left(id, 3).concat(StringUtils
.removeStart(StringUtils.leftPad(StringUtils.right(id, 3), StringUtils.length(id), "*"), "***"));
} /**
* [固定电话] 后四位,其他隐藏<例子:****1234>
*/
public static String fixedPhone(final String num) {
if (StringUtils.isBlank(num)) {
return "";
}
return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");
} /**
* [手机号码] 前三位,后四位,其他隐藏<例子:138******1234>
*/
public static String mobilePhone(final String num) {
if (StringUtils.isBlank(num)) {
return "";
}
return StringUtils.left(num, 2).concat(StringUtils
.removeStart(StringUtils.leftPad(StringUtils.right(num, 2), StringUtils.length(num), "*"), "***")); } /**
* [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护<例子:北京市海淀区****>
*
* @param sensitiveSize
* 敏感信息长度
*/
public static String address(final String address, final int sensitiveSize) {
if (StringUtils.isBlank(address)) {
return "";
}
final int length = StringUtils.length(address);
return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length, "*");
} /**
* [电子邮箱] 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示<例子:g**@163.com>
*/
public static String email(final String email) {
if (StringUtils.isBlank(email)) {
return "";
}
final 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>
*/
public static String bankCard(final String cardNum) {
if (StringUtils.isBlank(cardNum)) {
return "";
}
return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(
StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******"));
} /**
* [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号<例子:12********>
*/
public static String cnapsCode(final String code) {
if (StringUtils.isBlank(code)) {
return "";
}
return StringUtils.rightPad(StringUtils.left(code, 2), StringUtils.length(code), "*");
} }

4.测试

public class Test {

    private static final Logger logger=LoggerFactory.getLogger(Test.class);

    public static void main(String[] args) {
User user=new User();
user.setName("张三");
user.setPhone("18666218777");
user.setEmail("zhangsan@qq.com");
System.out.println(JSON.toJSONString(user.noSensitiveObj())); }
}

结果

{"email":"z*******@qq.com","name":"张*","phone":"18******77"}

经过和同事讨论后,发现其实不需要这么复杂,只要在model 的tostring 方法中脱敏即可。

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

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

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

  2. java 数据脱敏

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

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

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

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

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

  5. [翻译]Java日志终极指南

    本文由 ImportNew - Wing 翻译自 loggly.欢迎加入翻译小组.转载请见文末要求. Java日志基础 Java使用了一种自定义的.可扩展的方法来输出日志.虽然Java通过java.u ...

  6. Java日志规范

    前言 一个在生产环境里运行的程序如果没有日志是很让维护者提心吊胆的,有太多杂乱又无意义的日志也是令人伤神.程序出现问题时候,从日志里如果发现不了问题可能的原因是很令人受挫的.本文想讨论的是如何在Jav ...

  7. Java日志系统框架的设计与实现

    推荐一篇好的文章介绍java日志系统框架的设计的文章:http://soft.chinabyte.com/database/438/11321938.shtml 文章内容总结: 日志系统对跟踪调试.程 ...

  8. Java程序员最常用的8个Java日志框架

    转自:http://www.codeceo.com/article/8-java-log-framework.html 作为一名Java程序员,我们开发了很多Java应用程序,包括桌面应用.WEB应用 ...

  9. Java 日志管理最佳实践

    转:http://blog.jobbole.com/51155/ 日志记录是应用程序运行中必不可少的一部分.具有良好格式和完备信息的日志记录可以在程序出现问题时帮助开发人员迅速地定位错误的根源.对于开 ...

随机推荐

  1. c# 技巧

    1 遍历属性 Type t = typeof(Colors); PropertyInfo[] pInfo = t.GetProperties(); foreach (PropertyInfo pi i ...

  2. opencv学习之颜色空间转换cvtColor()

    我们生活中大多数看到的彩色图片都是RGB类型,但是在进行图像处理时,需要用到灰度图.二值图.HSV.HSI等颜色制式,opencv提供了cvtColor()函数来实现这些功能.首先看一下cvtColo ...

  3. UI布局 自定义布局

    今天学习了UI布局当中的自定义的布局的部分,在开始的时候先动手写了一个跟随手指移动的小兔子的实例,初步的了解了布局管理器的概念之后开始正式进行布局管理器,其中包括相对布局,线性布局,帧布局,表格布局, ...

  4. index unique scan 与index range scan等的区别

    存取Oracle当中扫描数据的方法(一) Oracle 是一个面向Internet计算环境的数据库.它是在数据库领域一直处于领先地位的甲骨文公司的产品.可以说Oracle关系数据库系统是目前世界上流行 ...

  5. [Note]Splay学习笔记

    开个坑记录一下学习Splay的历程. Code 感谢rqy巨佬的代码,让我意识到了Splay可以有多短,以及我之前的Splay有多么的丑... int fa[N], ch[N][2], rev[N], ...

  6. [转] Go 的并发模式:Context

    [转] Go 的并发模式:Context tips:昨天看了飞雪无情的关于 Context 的文章,对 go 中 Context 有了一个初步的认识.今天看到一个 go 官方博客的关于 Context ...

  7. opencv:图像去噪(椒盐噪声)

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  8. 有源汇有上下界最小流 (ZQU 1592)

    这道题跟求最大流的时候差不多. 都是先构造可行流,然后判断是否可行, 可行的话,就利用残余流量,构造从汇点t跑到源点s的最大流, 如何求出答案呢. 在第一次求可行流的dinic后,跟求最大流的时候一样 ...

  9. 概率dp 148 D

    概率dp 设 f(i,j)f(i,j) 表示有 ii 只白鼠,jj 只黑鼠时A先手胜的概率 初始状态 全白时,显然先手必胜 有一只黑鼠时,先手若抽到黑鼠则后手必胜,所以先手首回合必须抽到白鼠 f(i, ...

  10. 吴裕雄 python 机器学习——数据预处理标准化MinMaxScaler模型

    from sklearn.preprocessing import MinMaxScaler #数据预处理标准化MinMaxScaler模型 def test_MinMaxScaler(): X=[[ ...