首页 > 其他分享 >自定义注解进行数据脱敏

自定义注解进行数据脱敏

时间:2024-11-15 15:30:11浏览次数:1  
标签:totalLength jackson 自定义 suffixLength import 注解 com 脱敏 fasterxml

前言

有些时候,我们可能对输出的某些字段要做特殊的处理在输出到前端,比如:身份证号,电话等信息,在前端展示的时候我们需要进行脱敏处理,这时候通过自定义注解就非常的有用了。在Jackson中要自定义注解,我们可以通过@JacksonAnnotationsInside注解来实现,如下示例:

一、自定义注解

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveSerializer.class)
public @interface Sensitive {

    //加密开始位置
    int start()default 0 ;

    //加密结束位置
    int end() default 0 ;

    //加密掩码
    String mask() default "*" ;
}

二、自定义序列化处理器SensitiveSerializer

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 org.springframework.util.StringUtils;
import java.io.IOException;
import java.util.Collections;

/**
 * @author songwp
 * @date 2024-11-15
 * @desc 自定义序列化器,用于对敏感字段进行脱敏处理
 */
public class SensitiveSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private Sensitive sensitive;

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        String val = value;
        if (sensitive != null && StringUtils.hasLength(val)) {
            String m = sensitive.mask();
            int start = sensitive.start();
            int end = sensitive.end();
            int totalLength = value.length();
            if (totalLength <= 2) {
                val = totalLength == 1 ? value + m : value.substring(0, 1) + m;
            } else if (totalLength <= 6) {
                val = value.substring(0, 1) + String.join("", Collections.nCopies(totalLength - 2, m)) + value.substring(totalLength - 1);
            } else {
                int prefixLength = Math.min(start, totalLength - 1);
                int suffixLength = Math.min(end, totalLength - 1);
                if (prefixLength > totalLength) {
                    prefixLength = totalLength / 2;
                }
                if (suffixLength > totalLength) {
                    suffixLength = totalLength / 2;
                }
                int maskLength = Math.max(0, totalLength - (prefixLength + suffixLength));
                if (maskLength == 0) {
                    prefixLength -= 2;
                    suffixLength -= 2;
                    maskLength = Math.max(2, totalLength - (prefixLength + suffixLength));
                }
                prefixLength = Math.min(prefixLength, totalLength - 1);
                suffixLength = Math.min(suffixLength, totalLength - 1);
                maskLength = totalLength - prefixLength - suffixLength;
                val = value.substring(0, prefixLength) + String.join("", Collections.nCopies(maskLength, m)) + value.substring(totalLength - suffixLength);
            }
        }
        gen.writeString(val);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        sensitive = property.getAnnotation(Sensitive.class);
        return this;
    }
}

三、在输出的Java Bean中使用上面的注解

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.songwp.config.Sensitive;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;

/**
 * @author songwp
 * @version 1.0
 * @date 2024-11-15
 * @description: user domain
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
    @Sensitive(start = 2, end = 4)
    private String name;
    @Sensitive(start = 6, end = 4)
    private String idCard;
    @Sensitive(start = 4, end = 3)
    private String phone;
}

四、在前端展示结果如下:

 敏感数据得到了脱敏处理。

标签:totalLength,jackson,自定义,suffixLength,import,注解,com,脱敏,fasterxml
From: https://www.cnblogs.com/songweipeng/p/18548072

相关文章

  • go fiber: 抛出自定义异常
    一,代码:1,自定义错误类:packageconfigimport("fmt")//定义错误代码和错误信息typeMyErrorstruct{CodeintMsgstring}//需要定义通用的Error()方法func(eMyError)Error()string{returnfmt.Sprintf("Code:%d,Msg:%s",e.Code,e.M......
  • 织梦自定义图片字段报错 Call to a member function GetInnerText()
    问题:添加自定义图片字段时,前台打开当前栏目列表出现 Fatalerror:CalltoamemberfunctionGetInnerText()onstring 错误。解决方法:修改 customfields.func.php 文件:打开 /include/customfields.func.php 文件,搜索:  $fvalue=trim($ntag->GetInnerTe......
  • ABB AC900F学习笔记331:使用ST做自定义功能块,计算最近60秒的分钟均值和最近60分钟的小
    前面自己学习了在西门子TIA使用SCL编程,施耐德Unity中使用ST编程做分钟均值和小时均值的方法,今晚在家练习了在ABBFreelance中自定义功能块使用ST语言做分钟均值和小时均值。新建项目、插入硬件、仿真器、操作站等不做介绍。新建一个用户功能块池,下面建一个功能块类。功能块类定......
  • Rust ?(Rust错误传播运算符?)(用于简化错误处理,自动将错误从函数中返回)(可恢复错误Result<T
    文章目录Rust错误传播运算符:深入理解与应用1.错误处理的基础1.1`Result`枚举1.2`Option`枚举2.错误传播运算符(`?`)2.1基本语法2.2工作原理1.检查返回值2.提取`Ok`值2.3错误传播示例3.错误传播与自定义错误类型(没仔细看)3.1定义自定义错误类型3.2自定义......
  • echarts自定义tooltip
    tooltip配置tooltip:{show:true,trigger:'axis',formatter:params=>{letresult=`<div>${params[0].axisValue}</div>`params.forEach(item=>{if(......
  • @Around() 和 @Pointcut()注解的区别
    1. @Around 注解@Around是一种环绕通知(AroundAdvice),它允许你在目标方法执行前后都执行一些逻辑。这意味着你可以在方法调用之前、之后甚至在方法抛出异常时执行特定的逻辑。示例@Around("@annotation(myLock)")publicObjectaroundAdvice(ProceedingJoinPointjoinPoi......
  • 自定义序列化
    #ifndefAI_PACS_JSONTOSTRUCT_H#defineAI_PACS_JSONTOSTRUCT_H#include<iostream>#include<string>#include<unordered_map>#include<variant>#include<vector>#include<nlohmann/json.hpp>#include<stdexcept>......
  • 在Go中使用自定义类型与Swagger集成
    在Go语言中,自定义类型可以帮助我们更好地组织代码和增强可读性。在本篇博客中,我们将探讨如何创建一个自定义类型,并将其与Swagger文档集成,以便在API中正确序列化和展示。1.创建自定义类型首先,我们定义一个名为 RechargeType 的自定义类型。这个类型将用于表示不同的充值方式。......
  • R语言data.table导入数据实战:data.table使用自定义函数及Reduce函数实现一次性性多表
    R语言data.table导入数据实战:data.table使用自定义函数及Reduce函数实现一次性性多表连接、data.table使用自定义函数及Reduce函数实现一次性性多表连接目录R语言data.table导入数据实战:data.table使用自定义函数及Reduce函数实现一次性性多表连接#data.table是什么?#dat......
  • 深入理解Spring框架中的@Async注解实现异步任务
    目录1.引言2.环境准备3.启用异步支持4.创建异步任务5.调用异步任务6.运行应用7.使用@Async需要注意的地方8.结论在现代Web应用中,异步任务的执行变得越来越重要。Spring框架提供了强大的@Async注解,可以帮助开发者轻松实现异步任务。本文将详细介绍如何在Sprin......