SpringBoot 返回值使用注解脱敏

 一、所需依赖

          进入maven仓库https://mvnrepository.com/,搜索jackson-annotations ,选择com.fasterxml.jackson.core 分组下面的依赖,建议2.11版本。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.11.0</version>
</dependency>

二、创建所需的注解工具类

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

    /**
     * 脱敏数据类型
     */
    sensitiveTypeEnum type() default sensitiveTypeEnum.CUSTOMER;

    /**
     * 前置不需要打码的长度
     */
    int prefixNoMaskLen() default 0;

    /**
     * 后置不需要打码的长度
     */
    int suffixNoMaskLen() default 0;

    /**
     * 用什么打码
     */
    String symbol() default "*";
}

@NoArgsConstructor
@AllArgsConstructor
public class SensitiveSerialize extends JsonSerializer<String> implements ContextualSerializer {

    /**
     * 脱敏类型
     */
    private sensitiveTypeEnum sensitiveTypeEnum;

    /**
     * 前几位不脱敏
     */
    private Integer prefixNoMaskLen;

    /**
     * 最后几位不脱敏
     */
    private Integer suffixNoMaskLen;

    /**
     * 用什么打码
     */
    private String symbol;

    @Override
    public void serialize(final String origin, final JsonGenerator jsonGenerator,
                          final SerializerProvider serializerProvider) throws IOException {
        switch (sensitiveTypeEnum) {
            case CUSTOMER:
                jsonGenerator.writeString(DesensitizedUtils.desValue(origin, prefixNoMaskLen, suffixNoMaskLen, symbol));
                break;
            case NAME:
                jsonGenerator.writeString(DesensitizedUtils.chineseName(origin));
                break;
            case ID_CARD:
                jsonGenerator.writeString(DesensitizedUtils.idCardNum(origin));
                break;
            case PHONE:
                jsonGenerator.writeString(DesensitizedUtils.mobilePhone(origin));
                break;
            case ADDRESS:
                jsonGenerator.writeString(DesensitizedUtils.address(origin));
                break;
            default:
                throw new IllegalArgumentException("unknown sensitive type enum " + sensitiveTypeEnum);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(final SerializerProvider serializerProvider,
                                              final BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) {
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                Sensitive sensitive = beanProperty.getAnnotation(Sensitive.class);
                if (sensitive == null) {
                    sensitive = beanProperty.getContextAnnotation(Sensitive.class);
                }
                if (sensitive != null) {
                    return new SensitiveSerialize(sensitive.type(), sensitive.prefixNoMaskLen(),
                            sensitive.suffixNoMaskLen(), sensitive.symbol());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }

}

需要脱敏的枚举

public enum sensitiveTypeEnum {

    /**
     * 自定义
     */
    CUSTOMER,

    /**
     * 姓名
     */
    NAME,

    /**
     * 身份证
     */
    ID_CARD,

    /**
     * 手机号码
     */
    PHONE,

    /**
     * 地址脱敏
     */
    ADDRESS
}

 对字符串实际脱敏的代码块。

public class DesensitizedUtils {
    /**
     * 对字符串进行脱敏操作
     *
     * @param origin          原始字符串
     * @param prefixNoMaskLen 左侧需要保留几位明文字段
     * @param suffixNoMaskLen 右侧需要保留几位明文字段
     * @param maskStr         用于遮罩的字符串, 如'*'
     * @return 脱敏后结果
     */
    public static String desValue(String origin, int prefixNoMaskLen, int suffixNoMaskLen, String maskStr) {
        if (StringUtils.isBlank(origin) || "null".equals(origin)) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        for (int i = 0, n = origin.length(); i < n; i++) {
            if (i < prefixNoMaskLen) {
                sb.append(origin.charAt(i));
                continue;
            }
            if (i > (n - suffixNoMaskLen - 1)) {
                sb.append(origin.charAt(i));
                continue;
            }
            sb.append(maskStr);
        }
        return sb.toString();
    }

    /**
     * 【中文姓名】显示前1位, 后1位,比如:李*梦 李*
     *
     * @param fullName 姓名
     * @return 结果
     */
    public static String chineseName(String fullName) {
        if (StringUtils.isBlank(fullName) || "null".equals(fullName)) {
            return null;
        }
        if (fullName.length() > 2) {
            return desValue(fullName, 1, 1, "*");
        } else {
            return desValue(fullName, 1, 0, "*");
        }

    }

    /**
     * 【身份证号】显示前6位, 后4位,其他隐藏。
     *
     * @param id 身份证号码
     * @return 结果
     */
    public static String idCardNum(String id) {
        if (StringUtils.isBlank(id) || "null".equals(id)) {
            return null;
        }
        return desValue(id, 6, 4, "*");
    }

    /**
     * 【手机号码】前三位,后四位,其他隐藏。
     *
     * @param phone 手机号码
     * @return 结果
     */
    public static String mobilePhone(String phone) {
        if (StringUtils.isBlank(phone) || "null".equals(phone)) {
            return null;
        }
        return desValue(phone, 3, 4, "*");
    }

    /**
     * 【地址】前五位,后0位、其他隐藏
     *
     * @param address 地址
     * @return 结果
     */
    public static String address(String address) {
        if (StringUtils.isBlank(address) || "null".equals(address)) {
            return null;
        }
        return desValue(address, 5, 0, "*");
    }
}

Spring Boot的控制器方法可以使用不同的返回值类型。以下是一些常见的返回值类型: 1. 字符串:可以直接返回一个字符串,它将作为响应的主体内容返回给客户端。 ```java @GetMapping("/hello") public String hello() { return "Hello, World!"; } ``` 2. 对象:可以返回一个Java对象,Spring Boot将自动将其转换为JSON格式返回给客户端。 ```java @GetMapping("/user/{id}") public User getUser(@PathVariable Long id) { User user = userService.getUserById(id); return user; } ``` 3. ResponseEntity:可以使用ResponseEntity类来自定义响应的状态码、头部信息和主体内容。 ```java @GetMapping("/user/{id}") public ResponseEntity<User> getUser(@PathVariable Long id) { User user = userService.getUserById(id); if (user != null) { return ResponseEntity.ok(user); } else { return ResponseEntity.notFound().build(); } } ``` 4. ModelAndView:可以返回一个ModelAndView对象,用于控制视图的渲染和模型数据的传递。 ```java @GetMapping("/home") public ModelAndView home() { ModelAndView modelAndView = new ModelAndView("home"); modelAndView.addObject("message", "Welcome to my website!"); return modelAndView; } ``` 5. 其他类型:还可以返回其他类型,如InputStream、File等,用于直接返回文件或流给客户端。 ```java @GetMapping("/file") public ResponseEntity<Resource> getFile() throws IOException { Resource file = fileService.getFile(); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"") .body(file); } ``` 这只是一些常见的返回值类型,实际上还有很多其他的返回值类型可以使用。根据实际需求选择合适的返回值类型即可。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值