首页 > 其他分享 >SpringBoot中通过自定义Jackson注解实现接口返回数据脱敏

SpringBoot中通过自定义Jackson注解实现接口返回数据脱敏

时间:2023-07-16 14:12:58浏览次数:49  
标签:Jackson SpringBoot 自定义 annotation jackson import com public 脱敏

场景

SpringBoot中整合Sharding Sphere实现数据加解密/数据脱敏/数据库密文,查询明文:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131742091

上面讲的是数据库中存储密文,查询时使用明文的脱敏方式,如果是需要数据库中存储

明文,而在查询时返回处理后的数据,比如身份证号、手机号等敏感数据,可以通过如下方式。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi

实现

1、自定义Jackson注解

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;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive {
    //脱敏策略
    SensitiveStrategy strategy();
}

2、指定脱敏策略,这个规则根据业务具体需求去制定,下面只做演示

import java.util.function.Function;

/**
 * 脱敏策略,枚举类,针对不同的数据定制特定的策略
 */
public enum SensitiveStrategy {
    /**
     * 用户名
     */
    USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
    /**
     * 身份证
     */
    ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
    /**
     * 手机号
     */
    PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
    /**
     * 地址
     */
    ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****"));

    private final Function<String, String> desensitizer;
    SensitiveStrategy(Function<String, String> desensitizer) {
        this.desensitizer = desensitizer;
    }
    public Function<String, String> desensitizer() {
        return desensitizer;
    }
}

3、定制JSON序列化实现

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;

/**
 * 序列化注解自定义实现
 * JsonSerializer<String>:指定String 类型,serialize()方法用于将修改后的数据载入
 */
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
    private SensitiveStrategy strategy;
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws
            IOException {
        gen.writeString(strategy.desensitizer().apply(value));
    }
    /**
     * 获取属性上的注解属性
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws
            JsonMappingException {
        Sensitive annotation = property.getAnnotation(Sensitive.class);
        if (Objects.nonNull(annotation)&&Objects.equals(String.class,
                property.getType().getRawClass())) {
            this.strategy = annotation.strategy();
            return this;
        }
        return prov.findValueSerializer(property.getType(), property);
    }
}

4、新增User类,并对需要脱敏的字段添加注解,并指定脱敏策略

import com.badao.demo.sensitive.Sensitive;
import com.badao.demo.sensitive.SensitiveStrategy;
import lombok.Data;
import java.io.Serializable;

@Data
public class User implements Serializable {

    private static final long serialVersionUID = -5514139686858156155L;

    private Integer id;

    private Integer userId;

    @Sensitive(strategy = SensitiveStrategy.USERNAME)
    private String name;

    private Integer age;

}

5、编写controller进行测试

@RequestMapping("user")
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("save")
    public String save() {
        User user = new User();
        user.setUserId(new Random().nextInt( 1000 ) + 1);
        user.setName("badao"+user.getUserId());
        user.setAge(new Random().nextInt( 80 ) + 1);
        userService.insert(user);
        return "save success";
    }

    @RequestMapping("select")
    public User select() {
        List<User> all = userService.findAll();
        return all.size()>0?all.get(0):new User();
    }
}

测试效果

 

标签:Jackson,SpringBoot,自定义,annotation,jackson,import,com,public,脱敏
From: https://www.cnblogs.com/badaoliumangqizhi/p/17557799.html

相关文章

  • 开发自己的Prometheus Exporter、实现自定义指标
    PrometheusExporter基础知识PrometheusExporter的概念、工作原理 PrometheusExporter是一个用来收集和暴露指标数据的工具,通过与Prometheus监控系统一起使用。它的结构包括两个组件:Collector和Exporter:Collector:用于从目标应用程序或系统收集指标并将其转化为Prometheus......
  • Winform自定义控件之复合控件
    winform提供了很多控件供使用,如label;text;button;panel;checkbox等,在一些场景下,这些控件不能很好的满足使用或适应场景,就需要我们进行自定义控件。自定义控件有三种形式:1.组合控件:将vs提供的控件自定义组合打包成一个新的控件就叫做组合控件。可避免一些重复工作代码,这个很好理......
  • springboot中解决redissonClien无法注入,封装工具雷
    引用:https://blog.csdn.net/feiying0canglang/article/details/120464693问题来源前几天遇到一个循环依赖问题,是RedissonClient这个bean引起的。RedissonClient是由一个配置类(@Configuration注解的类)提供的,这配置类在初始化时(@PostConstruct注解的方法中)去获取RedissonClient这......
  • Springboot JPA 集成多租户
    背景:​ iot-kit项目用的是jpa,不是mybatis,项目中需要引入多租户参考文章:【讲解多租户的实现与原理】https://www.bilibili.com/video/BV1F84y1T7yf/?share_source=copy_web&vd_source=981718c4abc87423399e43793a5d3763https://callistaenterprise.se/blogg/teknik/2020/10/17......
  • 每日一题:SpringBoot中支持的事务类型
    以下是每种事务类型的作用、代码示例和对代码的解释:PROPAGATION_REQUIRED(默认):作用:如果当前存在事务,则方法将在该事务中运行;如果不存在事务,则创建一个新的事务。适用于大多数业务场景,确保方法在事务中执行,如果没有事务,则创建一个新的事务。代码示例:@Transactional(propagatio......
  • springboot配置2
    核心自动配置原理        @condition条件判断注解 如果没配过就给你配 依赖底层的condition注解 里面参数是条件配置类  红色的就是不满足条件的类 ......
  • springboot 配置
    配置文件yam 名字是固定的,yaml后缀也可以比XML更适合 大量的标记被浪费yml语法把空格玩到极致   如何编写yaml文件并绑定  只有这个组件是容器中的组件才能使用容器的功能@COmponent如何在properties编写 value配置对比     ......
  • springboot3
    通过maven项目构建springboot项目创建maven项目导入springboot依赖编写一个主程序 必须加上springboot注解 主函数的快捷键psvm;两个参数一个是主类,一个是主函数参数部署测试 打包成一个jar文件包,可以在命令行运行直接场景启动器  COntroller表现层包......
  • SpringBoot中整合Sharding Sphere实现数据加解密/数据脱敏/数据库密文,查询明文
    场景为防止数据泄露,需要在插入等操作时将某表的字段在数据库中加密存储,在需要查询使用时明文显示。ShardingSphereShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。......
  • SpringBoot中集成jasypt-spring-boot实现配置文件数据加密脱敏
    场景经常会遇到这样一种情况:项目的配置文件中总有一些敏感信息,比如数据源的url、用户名、密码....这些信息一旦被暴露那么整个数据库都将会被泄漏,那么如何将这些配置隐藏呢。除了使用手动将加密之后的配置写入到配置文件中,提取的时候再手动解密的方式,还可以使用如下方式。jas......