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