首页 > 编程语言 >Java 自定义脱敏注解实现

Java 自定义脱敏注解实现

时间:2023-10-21 11:23:20浏览次数:39  
标签:Java 自定义 jackson str import com annotation 脱敏

自定义注解

package com.yunmeng.iot.common.desensitization.annotation;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yunmeng.iot.common.desensitization.enums.SecretStrategy;
import com.yunmeng.iot.common.desensitization.strategy.StringSecretSerializer;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义字符串脱敏注解
 *
 * @author Linzj
 * @date 2023/8/9/009 17:42
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = StringSecretSerializer.class)
public @interface StringSecret {

    /**
     * 脱敏策略
     *
     * @return 结果
     */
    SecretStrategy strategy();

}

脱敏策略

package com.yunmeng.iot.common.desensitization.enums;

import lombok.Getter;

import java.util.function.Function;

/**
 * 脱敏策略,不同数据可选择不同的策略
 *
 * @author Linzj
 * @date 2023/8/9/009 17:57
 */
@Getter
public enum SecretStrategy {

    /**
     * 用户名脱敏
     */
    USERNAME(str -> str.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),

    /**
     * 身份证脱敏
     */
    ID_CARD(str -> str.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),

    /**
     * 手机号脱敏
     */
    PHONE(str -> str.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),

    /**
     * 地址脱敏
     */
    ADDRESS(str -> str.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****"));

    private final Function<String, String> desensitizer;

    SecretStrategy(Function<String, String> desensitizer) {
        this.desensitizer = desensitizer;
    }
}

序列化器实现

package com.yunmeng.iot.common.desensitization.strategy;

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 com.yunmeng.iot.common.desensitization.annotation.StringSecret;
import com.yunmeng.iot.common.desensitization.enums.SecretStrategy;

import java.io.IOException;
import java.util.Objects;

/**
 * 字符串类型序列化器实现
 *
 * @author Linzj
 * @date 2023/8/9/009 17:43
 */
public class StringSecretSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private SecretStrategy secretStrategy;

    /**
     * 步骤一
     * 方法来源于ContextualSerializer,获取属性上的注解属性,同时返回一个合适的序列化器
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        // 获取自定义注解
        StringSecret annotation = beanProperty.getAnnotation(StringSecret.class);
        // 注解不为空,且标注的字段为String
        if (Objects.nonNull(annotation) && Objects.equals(String.class, beanProperty.getType().getRawClass())) {
            this.secretStrategy = annotation.strategy();
            // 符合我们自定义情况,返回本序列化器,将顺利进入到该类中的serialize()方法中
            return this;
        }
        // 注解为空,字段不为String,寻找合适的序列化器进行处理
        return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
    }

    /**
     * 步骤二
     * 方法来源于JsonSerializer<String>:指定返回类型为String类型,serialize()将修改后的数据返回
     */
    @Override
    public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        if (Objects.isNull(secretStrategy)) {
            // 定义策略为空,返回原字符串
            jsonGenerator.writeString(s);
        } else {
            // 定义策略不为空,返回策略处理过的字符串
            jsonGenerator.writeString(secretStrategy.getDesensitizer().apply(s));
        }
    }
}

标签:Java,自定义,jackson,str,import,com,annotation,脱敏
From: https://www.cnblogs.com/Linzj5950/p/17778660.html

相关文章

  • Stream filter中自定义谓词变量
    在流式处理中,filter操作是用于筛选符合条件的元素并生成一个新的流。谓词(Predicate)是一个表示条件的函数式接口,用于定义筛选的条件。在Java中,StreamAPI提供了filter方法来执行筛选操作。filter方法接受一个谓词作为参数,该谓词描述了筛选的条件。谓词的函数式接口定义如......
  • java基础漏洞学习----基础命令执行漏洞
    java基础漏洞学习----基础命令执行漏洞基础命令执行常见方法1.ProcessBuilderpackagecom.example.servletdemo;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjavax.servlet.ServletException;importjavax.servl......
  • Java Stream流实现递归查询
    MySql数据库表结构模拟数据查询出所有数据,用父节点递归查询出所有子节点数据/***封装备注分类集合**@paramremarkTypeList备注分类集合*@return递归好的集合*/@OverridepublicList<RemarkType>queryRemarkTypeList(......
  • 小程序底层技术机制解读 - JavaScript编程语言
    JavaScript是小程序的核心编程语言之一,它在小程序中起着至关重要的作用。本文将深入探讨JavaScript在小程序底层技术机制中的作用,以及如何利用JavaScript来构建小程序应用。同时,我们还将提供一个简单的代码演示,以帮助读者更好地理解JavaScript在小程序中的应用。JavaScript在小程序......
  • javaweb-会话跟踪技术
    首先了解什么是会话?会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束,在一次会话中可以包含多次请求和响应 上述图例就是会话。会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自同一浏览器,以便在同一次会话的多次请求中共享数据 ......
  • java基础漏洞学习----文件操作漏洞
    java基础漏洞学习----文件操作漏洞前置基础知识https://www.cnblogs.com/thebeastofwar/p/17760812.html文件上传漏洞文件上传的方式1.通过文件流index.jsp<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOC......
  • Java类加载器
    Java中的类加载器Java中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由Java应用开发人员编写的。系统提供的类加载器主要有下面三个:引导类加载器(bootstrapclassloader):它用来加载Java的核心库,是用原生代码来实现的,并不继承自java.lang.ClassLoa......
  • MobPush如何在Android端自定义铃声
    随着移动应用竞争进入红海时代,如何在APP推送中别出心裁显得尤为重要。例如对自己的APP推送赋予独特的推送铃声,能够给用户更加理想的使用体验。1、个性化提醒铃声有助于当收到特定类型的消息时,用户能够立刻识别出来。2、不同的推送铃声可以用于区分消息的紧急程度,从而为用户是否查看......
  • 【Unity3D】UI Toolkit自定义元素
    1前言​UIToolkit支持通过继承VisualElement实现自定义元素,便于通过脚本控制元素。另外,UIToolkit也支持将一个容器及其所有子元素作为一个模板,便于通过脚本复制模板。​如果读者对UIToolkit不是太了解,可以参考以下内容。UIToolkit简介UIToolkit容器UIT......
  • 关于JAVA项目中的常用的异常处理情况
    JAVA项目中的常用的异常处理情况总结   在Java应用程序开发中,异常处理是至关重要的,因为它可以帮助您的程序应对各种不可预测的情况和错误。无论是在开发新项目还是在维护现有项目时,了解如何有效地处理异常是确保您的应用程序稳定性和可靠性的关键。本文将深入探讨Java项......