Java之自定义注解的使用

要实现用户信息加密,我们可以新建一个EncryptCorpUser类。

package com.cmit.kapok.system.entity.corp_user;

import com.cmit.kapok.system.utils.encrypt.anno.Encrypt;
import com.cmit.kapok.system.utils.sensitive.SensitiveStrategy;
import com.cmit.kapok.system.utils.sensitive.anno.Sensitive;
import lombok.Data;

@Data
public class EncryptCorpUser{
    @Sensitive(strategy = SensitiveStrategy.REALNAME)
    private String realName;
    @Sensitive(strategy = SensitiveStrategy.USERNAME)
    private String userName;
    @Encrypt
    private String smapUid;
}

将用户信息数据设置进这个类,即可完成加密。

这是为什么呢?原因是使用了自定义的注解@Sensitive和@Encrypt。

@Sensitive注解定义如下:

Sensitive.java

package com.cmit.kapok.system.utils.sensitive.anno;

import com.cmit.kapok.system.utils.sensitive.SensitiveJsonSerializer;
import com.cmit.kapok.system.utils.sensitive.SensitiveStrategy;
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();
}

SensitiveJsonSerializer.java

package com.cmit.kapok.system.utils.sensitive;

import com.cmit.kapok.system.utils.sensitive.anno.Sensitive;
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;

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);

    }
}

SensitiveStrategy.java

package com.cmit.kapok.system.utils.sensitive;

import java.util.function.Function;

public enum SensitiveStrategy {
    /**
     * Username sensitive strategy.
     */
    USERNAME(s -> s.replaceAll("(.).*", "$1***")),
    /**
     * Realname sensitive strategy.
     */
    REALNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
    /**
     * email sensitive strategy.
     */
    EMAIL(s -> s.replaceAll("(^\\w)[^@]*(@.*$)", "$1****$2")),
    /**
     * Id card sensitive type.
     */
    ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
    /**
     * Phone sensitive type.
     */
    PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
    /**
     * Address sensitive type.
     */
    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;
    }
}

 

@Encrypt注解定义如下:

Encrypt.java

package com.cmit.kapok.system.utils.encrypt.anno;

import com.cmit.kapok.system.utils.encrypt.EncryptJsonSerializer;
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 = EncryptJsonSerializer.class)
public @interface Encrypt {
}

EncryptJsonSerializer.java

package com.cmit.kapok.system.utils.encrypt;

import com.cmit.kapok.system.utils.RSAUtil;
import com.cmit.kapok.system.utils.encrypt.anno.Encrypt;
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;

public class EncryptJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        try {
            gen.writeString(RSAUtil.encrypt(value));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        Encrypt annotation = property.getAnnotation(Encrypt.class);
        if (Objects.nonNull(annotation)&&Objects.equals(String.class, property.getType().getRawClass())) {
            return this;
        }
        return prov.findValueSerializer(property.getType(), property);
    }
}

 

posted @ 2023-03-22 17:11  罗毅豪  阅读(94)  评论(0编辑  收藏  举报