当前位置: 首页 > news >正文

网络网站推广首荐乐云seo聊城冠县网站建设

网络网站推广首荐乐云seo,聊城冠县网站建设,做软件的叫什么职业,免费行情软件下载大全目录 🍸前言 🍻一、Jackson 序列化库 🍺二、方案实践 2.1 环境准备 2.2 依赖引入 2.3 代码编写 💞️三、接口测试 🍹四、章末 🍸前言 小伙伴们大家好,最近也是很忙啊,上次的文章…

目录

🍸前言

🍻一、Jackson 序列化库

🍺二、方案实践

        2.1 环境准备

        2.2 依赖引入

        2.3 代码编写

 💞️三、接口测试

🍹四、章末


🍸前言

        小伙伴们大家好,最近也是很忙啊,上次的文章分享了 Caffeine 本地缓存,文章链接如下:

【Caffeine】⭐️SpringBoot 项目整合 Caffeine 实现本地缓存_springboot caffeine-CSDN博客

        最近在别的技术分享上看到了数据脱敏的介绍,感觉平时接触的挺多的,比如个人私密信息在页面上显示的时候需要对部分信息加密,就像手机号中间几个位置用 “*” 代替(如下图),具体的实现也有很多方式,比如单独某一个接口需要加密,那么可以在接口返回值时处理下数据即可,但是如果过多的接口有此需求,挨个处理显然费时费力并且增加代码冗余,这个时候就可以选用全局处理的解决方案,实现一次编写,到处实现,具体的方案就是可以在序列化时处理数据 ,序列化工具常用的 Jackson 日常接触也很多

🍻一、Jackson 序列化库

        Jackson 是一个流行的 Java 序列化/反序列化库,专门用于处理 JSON 数据。它提供了一组功能强大且灵活的 API,可以帮助开发者在 Java 对象和 JSON 数据之间进行转换。有以下几个特性,灵活、高效、应用广泛(整合各种框架),比如我们经常接触的 web 系统,就是将后端的数据 Json 序列化后传递给前端实现的

🍺二、方案实践

        2.1 环境准备

        测试项目是基于 SpringBoot 框架的项目实现,另外接口测试使用 Apipost 实现模拟请求

        2.2 依赖引入

        因为使用的 SpringBoot 框架,所以在创建项目的时候就已经勾选了 web 模块,而这些模块已经集成了相关的 Jackson 包,依赖如下

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

        如果项目中没有的话,也可以手动引入,依赖如下: 

        注:手动引入的时候,需要注意下版本问题,项目启动的时候可能会遇到如下情况,这种情况我在博客上搜索了相关的文章,有讲解的不是很多,但是可行的一种方案就是自己不要指定版本,使用父依赖的即可解决

Error starting Tomcat context. Exception: org.springframework.beans.factory.BeanCreationException. Message: Error creating bean with name 'formContentFilter' defined in class path resource

        <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId>
<!--            <version>2.9.8</version>--></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId>
<!--            <version>2.9.8</version>--></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
<!--            <version>2.9.8</version>--></dependency><dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId>
<!--            <version>2.13.0</version> &lt;!&ndash; 替换为与你的Spring Boot兼容的版本 &ndash;&gt;--></dependency>
        2.3 代码编写

                2.3.1 脱敏数据类型枚举

                指定哪些类型的数据需要脱敏,命名为枚举类,方便后续调用

/*** @author HuangBen */
public enum SensitiveEnum {/*** 中文名*/CHINESE_NAME,/*** 身份证号*/ID_CARD,/*** 手机号*/MOBILE_PHONE,/*** 地址*/ADDRESS,/*** 电子邮件*/EMAIL,/*** 银行卡*/BANK_CARD,
}

                2.3.2  处理隐私数据工具类

                这里将已有的处理工具封装为一个工具类,方便设置参数以及调用,这里导入的工具类如果报错,说明并没有引入依赖,依赖如下:

        <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>
import org.apache.commons.lang3.StringUtils;/*** @author HuangBen */
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位。<例子:420**********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, 4), StringUtils.length(id), "*"),"***"));}/*** [手机号码] 前三位,后四位,其他隐藏<例子:138******1234>*/public static String mobilePhone(final 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 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), "*"),"******"));}}

                2.3.3 编写脱敏序列化实现类

                这里就是先用刚才工具类处理数据再进行序列化

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import java.io.IOException;
import java.util.Objects;/*** @author HuangBen*/
public class SensitiveSerialize extends JsonSerializer<String> implements ContextualSerializer {/*** 脱敏类型*/private SensitiveEnum type;@Overridepublic void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {switch (this.type) {case CHINESE_NAME: {jsonGenerator.writeString(SensitiveInfoUtils.chineseName(s));break;}case ID_CARD: {jsonGenerator.writeString(SensitiveInfoUtils.idCardNum(s));break;}case MOBILE_PHONE: {jsonGenerator.writeString(SensitiveInfoUtils.mobilePhone(s));break;}case ADDRESS: {jsonGenerator.writeString(SensitiveInfoUtils.address(s, 4));break;}case EMAIL: {jsonGenerator.writeString(SensitiveInfoUtils.email(s));break;}case BANK_CARD: {jsonGenerator.writeString(SensitiveInfoUtils.bankCard(s));break;}}}@Overridepublic JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {// 为空直接跳过if (beanProperty != null) {// 非 String 类直接跳过if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {SensitiveWrapped sensitiveWrapped = beanProperty.getAnnotation(SensitiveWrapped.class);if (sensitiveWrapped == null) {sensitiveWrapped = beanProperty.getContextAnnotation(SensitiveWrapped.class);}if (sensitiveWrapped != null) {// 如果能得到注解,就将注解的 value 传入 SensitiveSerializereturn new SensitiveSerialize(sensitiveWrapped.value());}}return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);}return serializerProvider.findNullValueSerializer(beanProperty);}public SensitiveSerialize() {}public SensitiveSerialize(final SensitiveEnum type) {this.type = type;}
}

                2.3.4  编写脱敏注解类

                通过此注解可以灵活标注哪些数据需要脱敏处理,并且标注对应的枚举类型;注意这里指定了序列化的实现类为我们自己刚定义的,具体实现的功能就是遇到此注解标注的字段,序列化的时候使用我们指定的序列化器,我们自定义的序列化器中对每种类型的字段都有相应的处理逻辑

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;/*** @author HuangBen */
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveSerialize.class)
public @interface SensitiveWrapped {/*** 脱敏类型* @return*/SensitiveEnum value();
}

                 2.3.5 编写测试实体类

                这里指定了 mobile , idcard 两个字段需要脱敏,并且指明了按照哪一种数据类型脱敏处理

import lombok.Data;/*** @author HuangBen */
@Data
public class UserEntity {/*** 用户ID*/private Long userId;/*** 用户姓名*/private String name;/*** 手机号*/@SensitiveWrapped(SensitiveEnum.MOBILE_PHONE)private String mobile;/*** 身份证号码*/@SensitiveWrapped(SensitiveEnum.ID_CARD)private String idCard;/*** 年龄*/private String sex;/*** 性别*/private int age;}

 💞️三、接口测试

        简单用一个 restful 接口测试下处理后的数据是否脱敏,接口如下:

        利用接口请求工具,确实按照我们指定的字段以及类型进行脱敏处理了,测试成功,结果如下:

 

🍹四、章末

        通过这种方式实现的数据脱敏处理,后续在使用的时候也很方便,有哪些需要处理的字段只需要在实体类的字段上方添加注解并且指定脱敏类型即可,符合开闭原则,并且遵循很少改动原有代码的规则;

        文章到这里就结束了~

http://www.yayakq.cn/news/902113/

相关文章:

  • 域名备案完成了怎么建设网站北京网站建设软件
  • 南京市住房和城乡建设部网站wordpress如何加入视频播放器
  • 网站建设有关书籍商城网站建设行情
  • 网站建设山西网站开发专业找什么工作
  • 网站的弹窗广告怎么做宁波seo教程app推广
  • 小企业网站建设制作平台网络运营团队
  • 做一个静态网站导航要多少钱论坛网站开发模板
  • 网站建设售后培训网站备案信息变更
  • 做铁合金用哪个外贸网站好网站建设导向
  • 网站建设简运维 简历嘉兴网站建设方案优化
  • 中国安能建设总公司网站邯郸最新通告今天
  • 静安集团网站建设连山区网站建设
  • 网站域名所有权证明外贸公司经营范围大全
  • 申请网站做自己的产品天津滨海新区旅游景点
  • 建设银行公积金预约网站首页php做视频分享网站
  • 北京网站建设第一html教程百度云
  • 自个网站关于建设二级网站的报告
  • 手机网站自动跳转怎么解决网站乱码解决办法
  • 基于ssh架构网站开发优化手机性能的软件
  • 南京网站推广哪家便宜公司备案 网站主办者名称
  • 响应式手机网站网站seo哪家好
  • 汕头选择免费网站优化WordPress调用画廊
  • 陕西营销型手机网站建设php成品网站下载
  • it在线学习网站开发设计方案表达
  • 企业网站建设费入什么科目wordpress附近商家
  • 多平台网站开发哈尔滨站建筑面积
  • 淘客那些网站怎么做的石家庄公司做网站
  • 但是网站相关内容和程序并没有建设完_其次网站公司给我公司的功能型网站制作多少钱
  • php网站怎么做静态化网站建设费需要摊销吗
  • 手机上如何制作自己的网站qq浏览器小程序