1. 新建注解

import com.hanhuide.hhde.enums.SensitiveTypeEnum;import java.lang.annotation.*;@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Desensitized {//    脱敏类型(规则)SensitiveTypeEnum type();
}

2. 脱敏类型(定义脱敏类型)

public enum SensitiveTypeEnum {/*** 中文名*/CHINESE_NAME,/*** 身份证号*/ID_CARD,/*** 座机号*/FIXED_PHONE,/*** 手机号*/MOBILE_PHONE,/*** 地址*/ADDRESS,/*** 电子邮件*/EMAIL,/*** 银行卡*/BANK_CARD,/*** 密码*/PASSWORD,/*** 车牌号*/CARNUMBER;
}

3.实现AnnotationFormatterFactory接口

import com.hanhuide.hhde.annotation.Desensitized;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.Parser;
import org.springframework.format.Printer;import java.util.HashSet;
import java.util.Set;/*** Deprecated为注解的名称** @author 韩惠德*/
public class DesensitizedAnnotationFormatterFactory implements AnnotationFormatterFactory<Desensitized> {/*** 返回为处理的变量的类型** @return*/@Overridepublic Set<Class<?>> getFieldTypes() {Set<Class<?>> hashSet = new HashSet<>();hashSet.add(String.class);return hashSet;}@Overridepublic Printer<?> getPrinter(Desensitized desensitized, Class<?> aClass) {return getFormatter(desensitized);}@Overridepublic Parser<?> getParser(Desensitized desensitized, Class<?> aClass) {return getFormatter(desensitized);}private DesensitizedFormatter getFormatter(Desensitized desensitized) {DesensitizedFormatter formatter = new DesensitizedFormatter();formatter.setTypeEnum(desensitized.type());return formatter;}}

4创建DesensitizedFormatter 格式化类实现Formatter

import com.hanhuide.hhde.enums.SensitiveTypeEnum;
import com.hanhuide.hhde.utils.DesensitizedUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.format.Formatter;import java.text.ParseException;
import java.util.Locale;public class DesensitizedFormatter implements Formatter<String> {private SensitiveTypeEnum typeEnum;public SensitiveTypeEnum getTypeEnum() {return typeEnum;}public void setTypeEnum(SensitiveTypeEnum typeEnum) {this.typeEnum = typeEnum;}@Overridepublic String parse(String valueStr, Locale locale) throws ParseException {if (StringUtils.isNotBlank(valueStr)) {switch (typeEnum) {case CHINESE_NAME:valueStr = DesensitizedUtils.chineseName(valueStr);break;case ID_CARD:valueStr = DesensitizedUtils.idCardNum(valueStr);break;case FIXED_PHONE:valueStr = DesensitizedUtils.fixedPhone(valueStr);break;case MOBILE_PHONE:valueStr = DesensitizedUtils.mobilePhone(valueStr);break;case ADDRESS:valueStr = DesensitizedUtils.address(valueStr, 8);break;case EMAIL:valueStr = DesensitizedUtils.email(valueStr);break;case BANK_CARD:valueStr = DesensitizedUtils.bankCard(valueStr);break;case PASSWORD:valueStr = DesensitizedUtils.password(valueStr);break;case CARNUMBER:valueStr = DesensitizedUtils.carNumber(valueStr);break;default:}}return valueStr;}@Overridepublic String print(String s, Locale locale) {return s;}
}

5.创建格式化工具类DesensitizedUtils

package com.hanhuide.hhde.utils;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.hanhuide.hhde.annotation.Desensitized;
import org.apache.commons.lang3.StringUtils;import java.lang.reflect.*;
import java.util.*;/*** @Title: DesensitizedUtils*/
public class DesensitizedUtils {/*** 【中文姓名】只显示第一个汉字,其他隐藏为2个星号,比如:李**** @param fullName* @return*/public static String chineseName(String fullName) {if (StringUtils.isBlank(fullName)) {return "";}String name = StringUtils.left(fullName, 1);return StringUtils.rightPad(name, StringUtils.length(fullName), "*");}/*** 【身份证号】显示最后四位,其他隐藏。共计18位或者15位,比如:*************1234** @param id* @return*/public static String idCardNum(String id) {if (StringUtils.isBlank(id)) {return "";}String num = StringUtils.right(id, 4);return StringUtils.leftPad(num, StringUtils.length(id), "*");}/*** 【固定电话 后四位,其他隐藏,比如1234** @param num* @return*/public static String fixedPhone(String num) {if (StringUtils.isBlank(num)) {return "";}return StringUtils.leftPad(StringUtils.right(num, 4), StringUtils.length(num), "*");}/*** 【手机号码】前三位,后四位,其他隐藏,比如135******10** @param num* @return*/public static String mobilePhone(String num) {if (StringUtils.isBlank(num)) {return "";}return StringUtils.left(num, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(num, 2), StringUtils.length(num), "*"), "***"));}/*** 【地址】只显示到地区,不显示详细地址,比如:北京市海淀区****** @param address* @param sensitiveSize 敏感信息长度* @return*/public static String address(String address, int sensitiveSize) {if (StringUtils.isBlank(address)) {return "";}int length = StringUtils.length(address);return StringUtils.rightPad(StringUtils.left(address, length - sensitiveSize), length, "*");}/*** 【电子邮箱 邮箱前缀仅显示第一个字母,前缀其他隐藏,用星号代替,@及后面的地址显示,比如:d**@126.com>** @param email* @return*/public static String email(String email) {if (StringUtils.isBlank(email)) {return "";}int index = StringUtils.indexOf(email, "@");if (index <= 1) {return email;} else {return StringUtils.rightPad(StringUtils.left(email, 1), index, "*").concat(StringUtils.mid(email, index, StringUtils.length(email)));}}/*** 【银行卡号】前六位,后四位,其他用星号隐藏每位1个星号,比如:6222600**********1234>** @param cardNum* @return*/public static String bankCard(String cardNum) {if (StringUtils.isBlank(cardNum)) {return "";}return StringUtils.left(cardNum, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(cardNum, 4), StringUtils.length(cardNum), "*"), "******"));}/*** 【密码】密码的全部字符都用*代替,比如:******** @param password* @return*/public static String password(String password) {if (StringUtils.isBlank(password)) {return "";}String pwd = StringUtils.left(password, 0);return StringUtils.rightPad(pwd, StringUtils.length(password), "*");}/*** 【车牌号】前两位后一位,比如:苏M****5** @param carNumber* @return*/public static String carNumber(String carNumber) {if (StringUtils.isBlank(carNumber)) {return "";}return StringUtils.left(carNumber, 2).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(carNumber, 1), StringUtils.length(carNumber), "*"), "**"));}
}

6.将DesensitizedAnnotationFormatterFactory添加到spring配置文件中

package com.hanhuide.hhde.config;import com.hanhuide.hhde.factory.DesensitizedAnnotationFormatterFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
@Slf4j
public class WebConfigurer implements WebMvcConfigurer {@Overridepublic void addFormatters(FormatterRegistry registry) {log.info("启用自定义注解!!!");registry.addFormatterForFieldAnnotation(new DesensitizedAnnotationFormatterFactory());}
}

6.创建实体类student测试效果

package com.hanhuide.hhde.dao;import com.hanhuide.hhde.annotation.BooleanFormat;
import com.hanhuide.hhde.annotation.Desensitized;
import com.hanhuide.hhde.annotation.Label;
import com.hanhuide.hhde.annotation.TimestampFormat;
import com.hanhuide.hhde.enums.SensitiveTypeEnum;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;import java.sql.Timestamp;
import java.util.Date;@Data
public class Student {@Label("姓名")String name;@Label("出生日期")@DateTimeFormatDate born;@Label("分数")double score;@BooleanFormat(trueTag = {"YES", "OK", "是", "不是"})private boolean exists;@TimestampFormatprivate Timestamp startTime;@Desensitized(type = SensitiveTypeEnum.CHINESE_NAME)private String chinaName;@Desensitized(type = SensitiveTypeEnum.MOBILE_PHONE)private String moble_phone;@Desensitized(type = SensitiveTypeEnum.CARNUMBER)private String carNumber;
}

7创建controller测试

package com.hanhuide.hhde.controller;import com.hanhuide.hhde.dao.CallRecordQuery;
import com.hanhuide.hhde.dao.CallRecordReport;
import com.hanhuide.hhde.dao.Student;
import com.hanhuide.hhde.service.CallRecordService;
import com.hanhuide.hhde.service.impl.CallRecordServiceImpl;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("hello")
@Slf4j
public class HelloController {@Autowiredprivate CallRecordService callRecordService;@ApiOperation(value = "测试自定义注解")@PostMapping(value = {"index"})public Student ceshi(Student student) {log.info("这个月的学生 student:[{}]", student);return student;}@ApiOperation(value = "测试自定义注解数据库返回信息")@PostMapping(value = {"ceshi"})public List<CallRecordReport> ceshi(CallRecordQuery callRecordQuery) {List<CallRecordReport> callRecordReportList = callRecordService.searchExportDetails(callRecordQuery);return callRecordReportList;}}

实现效果

测试发现在前端传回去的参数可以脱敏但是 直接获取mybatis 结果无法脱敏所以 需要创建拦截器 使用阿里fastjson实现数据库数据脱敏,请查看(https://blog.csdn.net/qq_27081015/article/details/103297316)

springboot自定义格式化注解(脱敏)相关推荐

  1. SpringBoot conditional注解和自定义conditional注解使用

    conditional注解是Springboot starter的基石,自动装配的时候会根据条件确定是否需要注入这个类. 含义:基于条件的注解. 作用:根据是否满足某个特定条件来决定是否创建某个特定的 ...

  2. springboot + 拦截器 + 注解 实现自定义权限验证

    springboot + 拦截器 + 注解 实现自定义权限验证 最近用到一种前端模板技术:jtwig,在权限控制上没有用springSecurity.因此用拦截器和注解结合实现了权限控制. 1.1 定 ...

  3. @retention注解作用_分分钟带你玩转SpringBoot自定义注解

    在工作中,我们有时候需要将一些公共的功能封装,比如操作日志的存储,防重复提交等等.这些功能有些接口会用到,为了便于其他接口和方法的使用,做成自定义注解,侵入性更低一点.别人用的话直接注解就好.下面就来 ...

  4. 元旦加班写SpringBoot自定义注解

    写在前面 这个点我们公司的人走的已经差不多了,原因很简单呀,明天元旦嘛,放假前可是不加班的,很nice,实习生的我,今天给大家分享一篇springboot自定义注解的技术文章. 很牛逼的注解 开发过程 ...

  5. Springboot自定义注解实现用户登录状态校验(一)

    Springboot自定义注解实现用户登录状态校验(一) 拦截器方式 定义注解类 import java.lang.annotation.*;/*** @author:小飞猪* @date:2020/ ...

  6. springboot 自定义注解拦截器

    springboot 自定义注解拦截器 最近在工作中,发现自定义注解拦截使用起来特别方便,现在来写出来给大家看看 环境springboot 首先写一个自定义注解 package com.study.c ...

  7. Springboot 自定义注解、切面

    本文实现的是使用自定义注解作为切入点. 1.创建springboot工程,引入依赖 本次任务实例主要引入以下两个依赖即可. <dependencies><dependency> ...

  8. SpringBoot 自定义注解+AOP+Redis 防止接口重复提交表单数据

    SpringBoot结合Redis处理重复提交 数据重复提交导致多次请求服务.入库,产生脏数据.冗余数据等情况.禁止重复提交使我们保证数据准确性及安全性的必要操作. 实际上,造成这种情况的场景不少: ...

  9. springboot 自定义注解开发

    适用场景: 同一个实体类(User)在多个地方用到,但是属性password只能设置为符合指定规则的字符,此时我们有pc和app端两处入口可以维护user的这个attribute,假设两处入口走不同的 ...

最新文章

  1. 洲际的merlin怎么用_洲际merlin登陆
  2. Android开发之关于transformDexArchiveWithExternalLibsDexMergerForDebug java.lang.OutOfMemoryError问题的参考解决方案
  3. 实现 Virtual DOM 下的一个 VNode 节点
  4. 光纤光信号闪红灯_电信光纤光猫光信号闪红灯怎么处理
  5. 笔记67 Spring Boot快速入门(七)
  6. Java实现简单工厂模式
  7. MySQL 8.0 API 使用STMT简单实例
  8. 集线器、网桥、交换机的区别(详解干货!!!)
  9. 【零样本学习】Zero-Shot Learning via Class-Conditioned Deep Generative Models
  10. 如何保证测试质量之Bug管理规范及流程
  11. java 解析dojo_Dojo入门三种HelloWorld!
  12. 内地酒量排行榜山东居首 东北三省无一进前三
  13. 安装AD域时先决条件不通过
  14. 每个人都应该具有创业精神 ——《穿布鞋的马云》读后感
  15. 十大常见的电子元器件
  16. Android 图片压缩、内存计算
  17. 瑞云渲染 | 全面支持Anima®4渲染插件,实现高精度的群集角色!
  18. 手写汉字数字识别详细过程(构建数据集+CNN神经网络+Tensorflow)
  19. 工业级洗地机器人_基于多传感器融合的自动洗地机器人避障研究
  20. mac下的python程序使用pyinstall打包

热门文章

  1. layui 图片上传 asmx C#
  2. 为什么特斯拉这么“嫌弃” 拼多多?
  3. postgresql and git
  4. uniapp支付宝小程序授权用户信息、授权手机号码
  5. 思科计算机网络 | 第一章路由器概念测试题(一)
  6. JVM Advent Calendar:将Kotlin性能与Graal和C2进行比较
  7. 蓝思科技预计今年第一季度净利润同比下降170%至200%
  8. yandex bot user agent
  9. python绘制立体心形折纸图解_立体幸运心、桃心简单折纸方法图解
  10. 计算机丛书之计算机安全全本阅读,网络安全技术之计算机安全.doc