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

成都建设网站那家好软文营销的经典案例

成都建设网站那家好,软文营销的经典案例,淮安维度网站建设,企业网站报价方案模板文章目录 引入认识 YAML 格式规范定义脱敏规则格式脱敏逻辑实现读取 YAML 配置文件获取脱敏规则通过键路径获取对应字段规则原始优化后 对数据进行脱敏处理递归生成字段对应的键路径脱敏测试 完整工具类 引入 在项目中遇到一个需求#xff0c;需要对交易接口返回结果中的指定… 文章目录 引入认识 YAML 格式规范定义脱敏规则格式脱敏逻辑实现读取 YAML 配置文件获取脱敏规则通过键路径获取对应字段规则原始优化后 对数据进行脱敏处理递归生成字段对应的键路径脱敏测试 完整工具类 引入 在项目中遇到一个需求需要对交易接口返回结果中的指定字段进行脱敏操作但又不能使用AOP注解的形式于是决定使用一种比较笨的方法 首先将所有需要脱敏字段及其对应脱敏规则存储到 Map 中。在接口返回时遍历结果中的所有字段判断字段名在 Map 中是否存在 如果不存在说明该字段不需要脱敏不做处理即可。如果存在说明该字段需要脱敏从 Map 中获取对应的脱敏规则进行脱敏。 最后返回脱敏之后的结果。 认识 YAML 格式规范 由于返回的结果涉及到嵌套 Map所以决定采用 YAML 格式的文件存储脱敏规则那么为了大家统一维护和开发就需要大家对 YAML 格式进行了解遵守规范不易出错少走弯路。 YAMLYAML Ain’t Markup Language与传统的 JSON、XML 和 Properties 文件一样都是用于数据序列化的格式常用于配置文件和数据传输。 相比于其他格式YAML 是一种轻量级的数据序列化格式它的设计初衷是为了简化复杂性提高人类可读性并且易于实现和解析。 与 JSON 相比YAML 在语法上更为灵活允许使用更简洁的方式来表示数据结构。 与 XML 相比YAML 的语法更为简洁没有繁琐的标签和尖括号。 与 Properties 相比YAML 支持更复杂的数据结构包括嵌套的键值对和列表。 除此之外YAML 还支持跨平台、跨语言可以被多种编程语言解析这使得YAML非常适合用于不同语言之间的数据传输和交换。 YAML 文件的语法非常简洁明了以下是它的语法规范 基本语法 使用 缩进表示层级关系可以使用空格或制表符进行缩进但不能混用。使用冒号:表示键值对键值对之间使用换行分隔。使用破折号-表示列表项列表项之间也使用换行分隔。 # 使用缩进表示层级关系 server:port: 8080# 使用冒号表示键值对 name: John Smith age: 30# 使用破折号表示列表项 hobbies:- reading- hiking- swimming注释 使用井号#表示注释在 # 后面的内容被视为注释可以出现在行首或行尾。 # 这是一个注释 name: John Smith age: 30 # 这也是一个注释字符串: 字符串可以使用单引号或双引号括起来也可以不使用引号。使用双引号时可以使用转义字符如 \n 表示换行和转义序列如 \u 表示 Unicode 字符。 # 使用双引号表示字符串 name: John Smith# 使用单引号表示字符串 nickname: Johnny键值对 键值对使用冒号:表示键和值之间使用一个 空格 分隔。键可以是字符串或纯量如整数、布尔值等。值可以是字符串、纯量、列表或嵌套的键值对。 # 键和值之间使用一个空格分隔 name: John Smith# 键可以是字符串或纯量 age: 30# 值可以是字符串、纯量、列表或嵌套的键值对 address:city: San Franciscostate: Californiazip: 94107列表 使用破折号-表示列表项。列表项可以是字符串、纯量或嵌套的列表或键值对。 # 使用破折号表示列表项 hobbies:- reading- hiking- swimming# 列表项可以是字符串、纯量或嵌套的列表或键值对 people:- name: John Smithage: 30- name: Jane Doeage: 25引用 使用表示引用使用*表示引用的内容。 # 使用表示引用 address: myaddresscity: San Franciscostate: Californiazip: 94107# 使用*表示引用的内容 shippingAddress: *myaddress多行文本块 使用|保留换行符保留文本块的精确格式。使用折叠换行符将文本块折叠成一行并根据内容自动换行。 # 使用|保留换行符 description: |This is amulti-linestring.# 使用折叠换行符 summary: This is a summarythat may containline breaks.数据类型 YAML支持多种数据类型包括字符串、整数、浮点数、布尔值、日期和时间等。可以使用标记来表示一些特殊的数据类型如 !!str 表示字符串类型、!!int 表示整数类型等。 # 使用标记表示数据类型 age: !!int 30 weight: !!float 65.5 isMale: !!bool true created: !!timestamp 2022-01-01 12:00:00多文件 可以使用—表示多个 YAML 文件之间的分隔符。每个文件可以使用任何 YAML 语法。 # 第一个YAML文件 name: John Smith age: 30---# 第二个YAML文件 hobbies:- reading- hiking- swimming定义脱敏规则格式 对于数据结构简单的接口返回结果脱敏规则格式定义为【交易号-字段-规则】 交易号:字段名:规则: /^(1[3-9][0-9])\d{4}(\d{4}$)/同时接口返回的结果中可能用有嵌套列表那么针对这种复杂的结构就定义格式为【交易号-字段列表-字段-规则】即 交易号:字段名(列表):字段名:规则: /^(1[3-9][0-9])\d{4}(\d{4}$)/使用这种层级结构我们完全可以通过 Map.get(Key) 的形式获取到指定交易指定字段的脱敏规则。 脱敏逻辑实现 读取 YAML 配置文件获取脱敏规则 首先创建 YAML 文件 desensitize.yml 添加对应交易字段的脱敏规则 Y3800:phone:rule: (\\d{3})\\d{4}(\\d{4})format: $1****$2idCard:rule: (?\\w{6})\\w(?\\w{4})format: * Y3801:idCard:rule: (?\\w{3})\\w(?\\w{4})format: list:phone:rule: (\\d{3})\\d{4}(\\d{4})format: $1$2定义脱敏工具类 DataDesensitizationUtils 编写我们的脱敏逻辑 public class DataDesensitizationUtils { }在 DataDesensitizationUtils 工具类中我们需要实现在项目启动时读取 desensitize.yml 文件中的内容并转为我们想要的 Map 键值对数据类型 /*** 读取yaml文件内容并转为Map* param yamlFile yaml文件路径* return Map对象*/ public static MapString, Object loadYaml(String yamlFile) {Yaml yaml new Yaml();try (InputStream in DataDesensitizationUtils.class.getResourceAsStream(yamlFile)) {return yaml.loadAs(in, Map.class);} catch (Exception e) {e.printStackTrace();}return null; }在上述代码中我们通过 getResourceAsStream 方法根据指定的 YAML 文件的路径从类路径中获取资源文件的输入流。 然后使用 loadAs 方法将输入流中的内容按照 YAML 格式进行解析并将解析结果转换为指定的 Map.class 类型。 最后使用 try-with-resources 语句来自动关闭输入流。 通过键路径获取对应字段规则 原始 在上文中我们已经将 desensitize.yml 文件中所有的脱敏规则都以 key-Value 的形式存储到了 Map 中因此我们只需要通过 Key 从 Map 中获取即可。接下来编写方法通过 Key 获取指定字段对应脱敏规则 public static void main(String[] args) {// 加载 YAML 文件并获取顶层的 Map 对象路径基于 resources 目录MapString, Object yamlMap loadYaml(/desensitize.yml);System.out.println(yamlMap);// 从顶层的 Map 中获取名为 Y3800 的嵌套 MapMapString, Object Y3800 (MapString, Object) yamlMap.get(Y3800);System.out.println(Y3800);// 从 Y3800 的嵌套 Map 中获取名为 phone 的嵌套 MapMapString, Object phone (MapString, Object) Y3800.get(phone);System.out.println(phone); }输出结果如下 {Y3800{phone{rule(\d{3})\d{4}(\d{4}), format$1****$2}, idCard{rule(?\w{3})\w(?\w{4}), format*}}, Y3801{name{rule.(?.), format}, idCard{rule(?\w{3})\w(?\w{4}), format}, list{card{rule\d(?\d{4}), format}}}} {phone{rule(\d{3})\d{4}(\d{4}), format$1****$2}, idCard{rule(?\w{3})\w(?\w{4}), format*}} {rule(\d{3})\d{4}(\d{4}), format$1****$2}转为 JSON 格式显示如下 输出 YAML 文件中的全部数据 {Y3800: {phone: {rule: (\\d{3})\\d{4}(\\d{4}),format: $1****$2},idCard: {rule: (?\\w{3})\\w(?\\w{4}),format: *}},Y3801: {name: {rule: .(?.),format: },idCard: {rule: (?\\w{3})\\w(?\\w{4}),format: },list: {card: {rule: \\d(?\\d{4}),format: }}} }输出 Y3800 层级下的数据 {phone: {rule: (\\d{3})\\d{4}(\\d{4}),format: $1****$2},idCard: {rule: (?\\w{3})\\w(?\\w{4}),format: *} }输出 phone 层级下的数据 {rule: (\\d{3})\\d{4}(\\d{4}),format: $1****$2 }在这里我们需要仔细思考一下在我们通过 Key 获取指定层级下的数据时我们需要不断的调用 Map.get(Key) 方法即结构每嵌套一次就需要一次 getKey那么这里是否有优化的方法呢 答案是有的因为有问题就会有答案。 优化后 首先我们需要先了解一个概念 Y3800:phone:rule: (\\d{3})\\d{4}(\\d{4})format: $1****$2当我们要从上述数据中获取 phone 的脱敏规则时我们需要先从 Map 中 get(Y3800) 获取 Y3800 下的数据再通过 get(phone) 获取 phone 下的规则那么 Y3800-phone 就是 phone 的键路径。 基于此我们可以实现这样一个方法我们直接给出指定字段的键路径在方法中通过递归的方式从 Map 中获取到该键路径下的所有数据然后返回即可。 即优化思路为通过递归和判断来遍历嵌套的 Map直到找到键路径所对应的最里层的嵌套 Map并返回该 Map 对象。 优化后方法如下 /*** 递归获取嵌套 Map 数据** param map 嵌套数据源的 Map* param keys 嵌套键路径* return 嵌套数据对应的 Map*/ SuppressWarnings(unchecked) public static MapString, Object getNestedMapValues(MapString, Object map, String... keys) {// 如果键路径为空或者第一个键不在 Map 中则返回 nullif (keys.length 0 || !map.containsKey(keys[0])) {return null;}// 获取第一个键对应的嵌套对象Object nestedObject map.get(keys[0]);// 如果键路径长度为 1说明已经到达最里层的嵌套 Map直接返回该 Map 对象if (keys.length 1) {if (nestedObject instanceof Map) {return (MapString, Object) nestedObject;} else {return null;}} else {// 如果嵌套对象是 Map继续递归查找下一个键的嵌套 Mapif (nestedObject instanceof Map) {return getNestedMapValues((MapString, Object) nestedObject, Arrays.copyOfRange(keys, 1, keys.length));} else {// 嵌套对象既不是 Map 也不是 List返回 nullreturn null;}} }调用方法时传入 Key 的嵌套路径即可 public static void main(String[] args) {// 加载 YAML 文件并获取顶层的 Map 对象MapString, Object yamlMap loadYaml(/desensitize.yml);System.out.println(yamlMap);// 获取 Y3800 - phone 下的数据转为 MapMapString, Object y3800PhoneMap YamlUtils.getNestedMap(yamlMap, Y3800, phone);System.out.println(Y3800 - phone : y3800NameMap); }具体来说主要分为以下几步 首先判断键路径是否为空或者第一个键是否在 Map 中。如果键路径为空或者第一个键不在 Map 中则返回 null。获取第一个键对应的嵌套对象。通过 get 方法获取第一个键对应的嵌套对象。判断是否到达最里层的嵌套 Map。如果键路径长度为 1说明已经到达最里层的嵌套 Map直接返回该 Map 对象。继续递归查找下一个键的嵌套 Map。如果嵌套对象是 Map则继续递归查找下一个键的嵌套 Map。返回结果。返回递归查找的结果。 对数据进行脱敏处理 获取到字段的脱敏规则后我们就可以编写方法实现对源数据做脱敏处理脱敏方法如下 /*** 使用指定规则对数据进行脱敏处理** param data 要进行脱敏处理的数据* param map 包含脱敏规则和格式的参数映射* - rule 表示脱敏规则的正则表达式* - format 表示替换脱敏部分的字符串默认为 ** return 脱敏后的数据*/ private static String desensitizeLogic(String data, MapString, Object map) {if (map.containsKey(rule)) {String rule (String) map.get(rule);String sign *;if (map.containsKey(format)) {sign (String) map.get(format);}return data.replaceAll(rule, sign);}return data; }递归生成字段对应的键路径 目前我们已经实现了通过字段的键路径获取到该字段对应规则的方法 getNestedMapValues()那么接下来我们只需要生成字段对应的键路径然后调用方法 getNestedMapValues() 获取到脱敏规则后调用 desensitizeLogic() 对源数据进行脱敏即可。 提供源数据格式如下 {txEntity: {idCard: 130428197001180384,name: 赵士杰,list: [{phone: 17631007015},{phone: 17631007015}]},txHeader: {servNo: Y3801} }根据上述数据结构首先我们需要从 txHeader 中获取 servNo之后递归遍历 txEntity 中的元素即可。 具体方法如下 /*** 对指定实体数据进行脱敏处理** param entity 要进行脱敏处理的实体数据* param servNo 当前交易的服务号用于记录日志* param path 当前实体数据在整个数据结构中的路径用于记录日志*/ public static void parseData(Object entity, String servNo, String path) {if (entity instanceof Map) {for (Map.EntryString, Object entry : ((MapString, Object) entity).entrySet()) {// 计算当前键值对在整个数据结构中的路径String currentPath path.isEmpty() ? entry.getKey() : path , entry.getKey();if (entry.getValue() instanceof Map) {// 如果当前值是 Map 类型则递归处理子节点parseData(entry.getValue(), servNo, currentPath);} else if (entry.getValue() instanceof List) {// 如果当前值是 List 类型则遍历列表中的每个元素并递归处理子节点for (Object item : (List) entry.getValue()) {if (item instanceof Map) {parseData(item, servNo, currentPath);}}} else {// 如果当前值不是 Map 或 List则进行脱敏处理String p servNo , currentPath;String[] keyPaths p.split(,);// 获取当前节点的脱敏规则和格式MapString, Object nestedMap getNestedMap(keyPaths);if(Objects.nonNull(nestedMap)){// 记录日志log.info(-----------------交易【{}】字段【{}】开始脱敏-----------------,servNo,currentPath.replace(,,-));log.info(原始值【{}:{}】,entry.getKey(),entry.getValue());log.info(脱敏规则:{},nestedMap);// 对当前节点的值进行脱敏处理String desensitized desensitizeLogic((String) entry.getValue(), nestedMap);entry.setValue(desensitized);// 记录日志log.info(脱敏值【{}:{}】,entry.getKey(),entry.getValue());log.info(-----------------交易【{}】字段【{}】脱敏结束-----------------,servNo,currentPath.replace(,,-));}}}} }该方法接收一个实体数据 entity一个服务号 servNo 和一个路径 path 作为参数。在方法体内会遍历实体数据的键值对并根据具体情况递归处理子节点或进行脱敏处理。 当实体数据的值为 Map 类型时方法会递归处理子节点当值为 List 类型时方法会遍历列表中的每个元素并递归处理子节点当值既不是 Map 也不是 List 时方法会根据服务号和路径获取脱敏规则并对当前节点的值进行脱敏处理并记录脱敏日志。 脱敏处理的具体逻辑和规则通过调用 getNestedMap 方法和 desensitizeLogic 方法来实现其中 getNestedMap 方法用于获取脱敏规则desensitizeLogic 方法用于根据脱敏规则对数据进行脱敏处理。 注请注意本文中提供的数据样例的层次结构是和 YAML 中定义的结构是一样的再通过上述方法递归后生成的键路径是和从 YAML 中获取规则所需的键路径是一致的因此可以直接调用 getNestedMapValues() 获取脱敏规则。在实际使用中其他数据结构需要重写该逻辑。 脱敏测试 编写 Main 方法调用 public class Demo {public static MapString, Object getData() {HashMapString, Object phone new HashMap();phone.put(phone, 17631007015);HashMapString, Object phone2 new HashMap();phone2.put(phone, 17631007015);ListHashMapString, Object list new ArrayList();list.add(phone);list.add(phone2);HashMapString, Object txEntity new HashMap();txEntity.put(name, 赵士杰);txEntity.put(idCard, 130428197001180384);txEntity.put(list, list);HashMapString, Object result new HashMap();result.put(txEntity, txEntity);HashMapString, Object txHeader new HashMap();txHeader.put(servNo, Y3801);result.put(txHeader, txHeader);return result;}public static void main(String[] args) {MapString, Object data getData();// 假设data中包含接口返回的数据if (data.containsKey(txHeader) data.get(txHeader) instanceof Map) {String servNo ((MapString, String) data.get(txHeader)).get(servNo);DataDesensitizationUtils.parseData(data.get(txEntity), servNo, );}}}运行测试控制台输出如下 -----------------交易【Y3801】字段【idCard】开始脱敏----------------- 原始值【idCard:130428197001180384】 脱敏规则:{rule(?\w{3})\w(?\w{4}), format} 脱敏值【idCard:1300384】 -----------------交易【Y3801】字段【idCard】脱敏结束----------------- -----------------交易【Y3801】字段【list-phone】开始脱敏----------------- 原始值【phone:17631007015】 脱敏规则:{rule(\d{3})\d{4}(\d{4}), format$1$2} 脱敏值【phone:1767015】 -----------------交易【Y3801】字段【list-phone】脱敏结束----------------- -----------------交易【Y3801】字段【list-phone】开始脱敏----------------- 原始值【phone:17631007015】 脱敏规则:{rule(\d{3})\d{4}(\d{4}), format$1$2} 脱敏值【phone:1767015】 -----------------交易【Y3801】字段【list-phone】脱敏结束-----------------数据脱敏后如下 {txEntity: {idCard: 1300384,name: 赵士杰,list: [{phone: 1767015},{phone: 1767015}]},txHeader: {servNo: Y3801} }完整工具类 封装成完整的工具类如下 /*** ClassName DataDesensitizationUtils* Description 数据脱敏工具类* Author 赵士杰* Date 2024/1/25 20:15*/ Slf4j SuppressWarnings(unchecked) public class DataDesensitizationUtils {// YAML 文件路径private static final String YAML_FILE_PATH /tuomin.yml;// 存储解析后的 YAML 数据private static MapString, Object map;static {// 创建 Yaml 对象Yaml yaml new Yaml();// 通过 getResourceAsStream 获取 YAML 文件的输入流try (InputStream in DataDesensitizationUtils.class.getResourceAsStream(YAML_FILE_PATH)) {// 解析 YAML 文件为 Map 对象map yaml.loadAs(in, Map.class);} catch (Exception e) {e.printStackTrace();}}/*** 获取嵌套的 Map 数据** param keys 嵌套键路径* return 嵌套数据对应的 Map*/private static MapString, Object getNestedMap(String... keys) {return getNestedMapValues(map, keys);}/*** 递归获取嵌套 Map 数据** param map 嵌套数据源的 Map* param keys 嵌套键路径* return 嵌套数据对应的 Map*/private static MapString, Object getNestedMapValues(MapString, Object map, String... keys) {// 如果键路径为空或者第一个键不在 Map 中则返回 nullif (keys.length 0 || !map.containsKey(keys[0])) {return null;}// 获取第一个键对应的嵌套对象Object nestedObject map.get(keys[0]);// 如果键路径长度为 1说明已经到达最里层的嵌套 Map直接返回该 Map 对象if (keys.length 1) {if (nestedObject instanceof Map) {return (MapString, Object) nestedObject;} else {return null;}} else {// 如果嵌套对象是 Map继续递归查找下一个键的嵌套 Mapif (nestedObject instanceof Map) {return getNestedMapValues((MapString, Object) nestedObject, Arrays.copyOfRange(keys, 1, keys.length));} else {// 嵌套对象既不是 Map 也不是 List返回 nullreturn null;}}}/*** 对指定实体数据进行脱敏处理** param entity 要进行脱敏处理的实体数据* param servNo 当前交易的服务号用于记录日志* param path 当前实体数据在整个数据结构中的路径用于记录日志*/public static void parseData(Object entity, String servNo, String path) {if (entity instanceof Map) {for (Map.EntryString, Object entry : ((MapString, Object) entity).entrySet()) {String currentPath path.isEmpty() ? entry.getKey() : path , entry.getKey();if (entry.getValue() instanceof Map) {parseData(entry.getValue(), servNo, currentPath);} else if (entry.getValue() instanceof List) {for (Object item : (List) entry.getValue()) {if (item instanceof Map) {parseData(item, servNo, currentPath);}}} else {String p servNo , currentPath;String[] keyPaths p.split(,);MapString, Object nestedMap getNestedMap(keyPaths);if (Objects.nonNull(nestedMap)) {log.info(-----------------交易【{}】字段【{}】开始脱敏-----------------, servNo, currentPath.replace(,, -));log.info(原始值【{}:{}】, entry.getKey(), entry.getValue());log.info(脱敏规则:{}, nestedMap);String desensitized desensitizeLogic((String) entry.getValue(), nestedMap);entry.setValue(desensitized);log.info(脱敏值【{}:{}】, entry.getKey(), entry.getValue());log.info(-----------------交易【{}】字段【{}】脱敏结束-----------------, servNo, currentPath.replace(,, -));}}}}}/*** 脱敏逻辑* param data 源数据* param map 脱敏规则* return 脱敏后的数据*/private static String desensitizeLogic(String data, MapString, Object map) {if (map.containsKey(rule)) {String rule (String) map.get(rule);String sign *;if (map.containsKey(format)) {sign (String) map.get(format);}return data.replaceAll(rule, sign);}return data;}}
http://www.w-s-a.com/news/863965/

相关文章:

  • 类似百度的网站移动端的网站怎么做的
  • 网站开发需要什么文凭网站分析的优劣势
  • 海尔网站建设不足之处山东网站营销
  • 楚雄 网站建设广告设计一般人能学吗
  • 热搜榜排名前十山东seo多少钱
  • 衡水哪有建网站的吗企业信息系统英文
  • 有模板怎么建站wordpress媒体库图片路径
  • 怎么做网站h汉狮企业网站营销的实现方式
  • 新津县建设局网站怎么做区块链网站
  • 网站设计与制作是什么专业广州优化网站
  • 腾讯有做淘宝客网站吗网站开发包
  • 网站整体营销方案网站建设百度贴吧
  • 宣传式网站养生网站模板
  • 临猗网站建设天津做网站哪家服务好
  • 郑州做网站九零后用织梦建设网站的步骤
  • 莱芜网站优化加徽信xiala5江都网站制作
  • 网站开发工具书焦作网站开发公司电话
  • 石狮网站建设报价百度爱采购怎么优化排名
  • 广州网站开发系统如何建设百度网站
  • 免费建立一个个人网站网站流量图怎么做
  • 微信网站建设公司首选网站后台更新 前台不显示
  • 撰写网站专题活动策划方案未成年做网站
  • 免费在线响应式网站自助建站网页设计与网站建设试卷
  • 四川省肿瘤医院搜索优化整站优化
  • 新钥匙建站深圳创业补贴政策2023
  • 建网站需要准备什么网站三个月没排名
  • 网站运营规划网站推广的手段
  • cvm可以做网站服务器吗网片围栏
  • 培训前端网站开发网站开发 群
  • 成都武侯区网站建设wordpress菜单分类目录