我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java怎么用Jackson序列化实现数据脱敏

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java怎么用Jackson序列化实现数据脱敏

这篇“Java怎么用Jackson序列化实现数据脱敏”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java怎么用Jackson序列化实现数据脱敏”文章吧。

    1.背景

    在项目中有些敏感信息不能直接展示,比如客户手机号、身份证、车牌号等信息,展示时均需要进行数据脱敏,防止泄露客户隐私。脱敏即是对数据的部分信息用脱敏符号(*)处理。

    2.目标

    • 在服务端返回数据时,利用Jackson序列化完成数据脱敏,达到对敏感信息脱敏展示。

    • 降低重复开发量,提升开发效率

    • 形成统一有效的脱敏规则

    • 可基于重写默认脱敏实现的desensitize方法,实现可扩展、可自定义的个性化业务场景的脱敏需求

    3.主要实现

    3.1基于Jackson的自定义脱敏序列化实现

    StdSerializer:所有标准序列化程序所使用的基类,这个是编写自定义序列化程序所推荐使用的基类。

    ContextualSerializer: 是Jackson 提供的另一个序列化相关的接口,它的作用是通过字段已知的上下文信息定制JsonSerializer。

    package com.jd.ccmp.ctm.constraints.serializer;import com.fasterxml.jackson.core.JsonGenerator;import com.fasterxml.jackson.databind.BeanProperty;import com.fasterxml.jackson.databind.JsonSerializer;import com.fasterxml.jackson.databind.SerializerProvider;import com.fasterxml.jackson.databind.ser.ContextualSerializer;import com.fasterxml.jackson.databind.ser.std.StdSerializer;import com.jd.ccmp.ctm.constraints.Symbol;import com.jd.ccmp.ctm.constraints.annotation.Desensitize;import com.jd.ccmp.ctm.constraints.desensitization.Desensitization;import com.jd.ccmp.ctm.constraints.desensitization.DesensitizationFactory;import com.jd.ccmp.ctm.constraints.desensitization.DefaultDesensitization;import java.io.IOException;public class ObjectDesensitizeSerializer extends StdSerializer<Object> implements ContextualSerializer {    private static final long serialVersionUID = -7868746622368564541L;    private transient Desensitization<Object> desensitization;    protected ObjectDesensitizeSerializer() {        super(Object.class);    }    public Desensitization<Object> getDesensitization() {        return desensitization;    }    public void setDesensitization(Desensitization<Object> desensitization) {        this.desensitization = desensitization;    }    @Override    public JsonSerializer<Object> createContextual(SerializerProvider prov, BeanProperty property) {//获取属性注解        Desensitize annotation = property.getAnnotation(Desensitize.class);        return createContextual(annotation.desensitization());    }    @SuppressWarnings("unchecked")    public JsonSerializer<Object> createContextual(Class<? extends Desensitization<?>> clazz) {        ObjectDesensitizeSerializer serializer = new ObjectDesensitizeSerializer();        if (clazz != DefaultDesensitization.class) {            serializer.setDesensitization((Desensitization<Object>) DesensitizationFactory.getDesensitization(clazz));        }        return serializer;    }    @Override    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {        Desensitization<Object> objectDesensitization = getDesensitization();        if (objectDesensitization != null) {            try {                gen.writeObject(objectDesensitization.desensitize(value));            } catch (Exception e) {                gen.writeObject(value);            }        } else if (value instanceof String) {            gen.writeString(Symbol.getSymbol(((String) value).length(), Symbol.STAR));        } else {            gen.writeObject(value);        }

    注:createContextual可以获得字段的类型以及注解。当字段拥有自定义注解时,取出注解中的值创建定制的序列化方式,这样在serialize方法中便可以得到这个值了。createContextual方法只会在第一次序列化字段时调用(因为字段的上下文信息在运行期不会改变),所以无需关心性能问题。

    3.2定义脱敏接口、以及工厂实现

    3.2.1脱敏器接口定义

    package com.jd.ccmp.ctm.constraints.desensitization;public interface Desensitization<T> {        T desensitize(T target);}

    3.2.2脱敏器工厂实现

    package com.jd.ccmp.ctm.constraints.desensitization;import java.util.HashMap;import java.util.Map;public class DesensitizationFactory {    private DesensitizationFactory() {    }    private static final Map<Class<?>, Desensitization<?>> map = new HashMap<>();    @SuppressWarnings("all")    public static Desensitization<?> getDesensitization(Class<?> clazz) {        if (clazz.isInterface()) {            throw new UnsupportedOperationException("desensitization is interface, what is expected is an implementation class !");        }        return map.computeIfAbsent(clazz, key -> {            try {                return (Desensitization<?>) clazz.newInstance();            } catch (InstantiationException | IllegalAccessException e) {                throw new UnsupportedOperationException(e.getMessage(), e);            }        });

    3.3常用的脱敏器实现

    3.3.1默认脱敏实现

    可基于默认实现,扩展实现个性化场景

    package com.jd.ccmp.ctm.constraints.desensitization;public interface DefaultDesensitization extends Desensitization<String> {}

    3.3.2手机号脱敏器

    实现对手机号中间4位号码脱敏

    package com.jd.ccmp.ctm.constraints.desensitization;import com.jd.ccmp.ctm.constraints.Symbol;import java.util.regex.Matcher;import java.util.regex.Pattern;public class MobileNoDesensitization implements DefaultDesensitization {        private static final Pattern DEFAULT_PATTERN = Pattern.compile("(13[0-9]|14[579]|15[0-3,5-9]|16[6]|17[0135678]|18[0-9]|19[89])\d{8}");    @Override    public String desensitize(String target) {        Matcher matcher = DEFAULT_PATTERN.matcher(target);        while (matcher.find()) {            String group = matcher.group();            target = target.replace(group, group.substring(0, 3) + Symbol.getSymbol(4, Symbol.STAR) + group.substring(7, 11));        }        return target;

    3.4注解定义

    通过@JacksonAnnotationsInside实现自定义注解,提高易用性

    package com.jd.ccmp.ctm.constraints.annotation;import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;import com.fasterxml.jackson.databind.annotation.JsonSerialize;import com.jd.ccmp.ctm.constraints.desensitization.Desensitization;import com.jd.ccmp.ctm.constraints.serializer.ObjectDesensitizeSerializer;import java.lang.annotation.*;@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@JacksonAnnotationsInside@JsonSerialize(using = ObjectDesensitizeSerializer.class)@Documentedpublic @interface Desensitize {        @SuppressWarnings("all")    Class<? extends Desensitization<?>> desensitization();

    3.4.1默认脱敏注解

    package com.jd.ccmp.ctm.constraints.annotation;import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;import com.jd.ccmp.ctm.constraints.desensitization.DefaultDesensitization;import java.lang.annotation.*;@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@JacksonAnnotationsInside@Desensitize(desensitization = DefaultDesensitization.class)@Documentedpublic @interface DefaultDesensitize {

    3.4.2手机号脱敏注解

    package com.jd.ccmp.ctm.constraints.annotation;import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;import com.jd.ccmp.ctm.constraints.desensitization.MobileNoDesensitization;import java.lang.annotation.*;@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@JacksonAnnotationsInside@Desensitize(desensitization = MobileNoDesensitization.class)@Documentedpublic @interface MobileNoDesensitize {}

    3.5定义脱敏符号

    支持指定脱敏符号,例如* 或是 ^_^

    package com.jd.ccmp.ctm.constraints;import java.util.stream.Collectors;import java.util.stream.IntStream;public class Symbol {        public static final String STAR = "*";    private Symbol() {}        public static String getSymbol(int number, String symbol) {        return IntStream.range(0, number).mapToObj(i -> symbol).collect(Collectors.joining());    }

    4.使用样例&执行流程剖析

    Java怎么用Jackson序列化实现数据脱敏

    程序类图

    Java怎么用Jackson序列化实现数据脱敏

    **执行流程剖析**

     1.调用JsonUtil.toJsonString()开始执行序列化

     2.识别属性mobile上的注解@MobileNoDesensitize(上文3.4.2)

     3.调用ObjectDesensitizeSerializer#createContextual(上文3.1 & 3.2),返回JsonSerializer

     4.调用手机号脱敏实现MobileNoDesensitization#desensitize(上文3.3.2)

     5.输出脱敏后的序列化结果,{"mobile":"133****5678"}

    不难发现核心执行流程是第3步,但是@MobileNoDesensitize与ObjectDesensitizeSerializer又是如何联系起来的呢?

    • 尝试梳理下引用链路:@MobileNoDesensitize -> @Desensitize -> @JsonSerialize -> ObjectDesensitizeSerializer

    • 但是,在ObjectDesensitizeSerializer的实现中,我们似乎却没有发现上述链路的直接调用关系

    • 这就不得不说下Jackson元注解的概念

    //1.提到元注解这个词,大家会想到@Target、@Retention、@Documented、@Inherited//2.Jackson也以同样的思路设计了@JacksonAnnotationsInside@Target({ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@JacksonAnnotationpublic @interface JacksonAnnotationsInside{}

    正是通过”combo-annotations”(组合注解、捆绑注解)的机制,实现了指示Jackson应该使用其拥有的元注释,而不是使用目标注释,从而实现了自定义脱敏实现设计目标。

    以上就是关于“Java怎么用Jackson序列化实现数据脱敏”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Java怎么用Jackson序列化实现数据脱敏

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Java怎么用Jackson序列化实现数据脱敏

    这篇“Java怎么用Jackson序列化实现数据脱敏”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java怎么用Jackso
    2023-07-05

    Java利用Jackson序列化实现数据脱敏详解

    在项目中有些敏感信息不能直接展示,比如客户手机号、身份证、车牌号等信息,展示时均需要进行数据脱敏,防止泄露客户隐私。本文将利用Jackson序列化实现数据脱敏,需要的可以参考一下
    2023-05-13

    Jackson反序列化时怎么实现大小写不敏感设置

    这篇文章主要讲解了“Jackson反序列化时怎么实现大小写不敏感设置”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Jackson反序列化时怎么实现大小写不敏感设置”吧!常用配置ObjectM
    2023-06-20

    Jackson多态序列化怎么实现

    这篇文章主要介绍“Jackson多态序列化怎么实现”,在日常操作中,相信很多人在Jackson多态序列化怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Jackson多态序列化怎么实现”的疑惑有所帮助!
    2023-07-02

    jackson多态反序列化怎么实现

    在Jackson中,实现多态反序列化可以使用@JsonTypeInfo注解和@JsonSubTypes注解。首先,在父类上使用@JsonTypeInfo注解,指定多态类型的字段名和默认的多态类型处理策略。例如:@JsonTypeInfo(
    2023-10-22

    怎么用java实现序列化

    这篇文章主要介绍怎么用java实现序列化,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!package test;import java.io.*;public class Test implements Serial
    2023-06-03

    Java怎么通过注解实现接口输出时数据脱敏

    小编给大家分享一下Java怎么通过注解实现接口输出时数据脱敏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Java注解实现接口输出数据脱敏在后台管理中,对于手机号
    2023-06-22

    Java序列化与反序列化怎么实现

    本篇内容主要讲解“Java序列化与反序列化怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java序列化与反序列化怎么实现”吧!序列化与反序列化概念序列化 (Serialization)是
    2023-06-02

    Python怎么实现数据序列化

    这篇文章主要介绍“Python怎么实现数据序列化”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python怎么实现数据序列化”文章能帮助大家解决问题。在日常开发中,对数据进行序列化和反序列化是常见的
    2023-07-06

    Java的序列化与反序列化怎么实现

    本篇内容介绍了“Java的序列化与反序列化怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Java对象的序列化Java平台允许我们在内
    2023-07-04

    用Gob在Golang中实现数据序列化/反序列化

    在 golang 中使用 gob 包序列化数据需以下步骤:为要序列化的类型实现 gobencode 和 gobdecode 接口。使用 gob.newencoder 和 gob.newdecoder 创建编码器和解码器。使用编码器对数据进行
    用Gob在Golang中实现数据序列化/反序列化
    2024-04-08

    java中序列化Serializable怎么实现

    要实现Java中的对象序列化,需要按照以下步骤进行:1. 在需要进行序列化的类上实现`Serializable`接口。`Serializable`接口是一个标记接口,不包含任何方法,只是用来标记该类可以被序列化。```javapublic
    2023-09-14

    Java对象序列化怎么实现

    本篇内容介绍了“Java对象序列化怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!从 Java 类产生 XML 把 Ajax 响应作为
    2023-06-03

    hbase怎么实现数据的时间序列化

    在HBase中,数据的时间序列化通常通过以下方式实现:使用Timestamp作为数据的时间戳:在HBase中,每条数据都会有一个时间戳(Timestamp)与之关联。时间戳通常用于标识数据的版本,可以帮助在数据更新或删除时区分不同版本的数据
    hbase怎么实现数据的时间序列化
    2024-03-05

    怎么使用Thrift实现跨语言Redis数据序列化

    使用Thrift实现跨语言Redis数据序列化的步骤如下:定义Thrift文件:首先需要定义一个Thrift文件,定义需要序列化的数据结构和接口。例如,可以定义一个简单的结构来表示Redis中的键值对:struct KeyValue {1:
    怎么使用Thrift实现跨语言Redis数据序列化
    2024-04-29

    怎么用Node.js和Redis实现有效的数据序列化

    要使用Node.js和Redis实现有效的数据序列化,您可以使用Node.js中的redis模块来连接和操作Redis数据库,并使用Node.js中的JSON.stringify和JSON.parse方法来序列化和反序列化数据。以下是一个
    怎么用Node.js和Redis实现有效的数据序列化
    2024-04-29

    怎么用java实现一个简单的序列化

    小编给大家分享一下怎么用java实现一个简单的序列化,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! package test;import Java.io.*;
    2023-06-03

    怎么使用C#实现XML序列化

    本篇内容主要讲解“怎么使用C#实现XML序列化”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么使用C#实现XML序列化”吧!一、使用 System.Xml.Serialization类1、定义
    2023-06-30

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录