Annotation Driven Masking (With. Jackson Library)
Custom Annotation 생성
Custom Annotation Type 정의
public enum MaskingType {
NAME,
CONTACT,
EMAIL,
CREDIT_CARD,
BIRTHDAY
}
Custom Annotation 정의
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@JsonSerialize(using = StringPropertyMasker.class)
public @interface Masked {
MaskingType type();
}
마스킹 메서드 구현
public class Masking {
public static String mask(MaskingType type, String value) {
if (type == null) return value;
String str = "";
switch (type) {
case NAME:
str = NameMaskOf(value);
break;
case CONTACT:
str = ContactMaskOf(value);
break;
case BIRTHDAY:
str = BirthDayMaskOf(value);
break;
default:
str = value;
break;
}
return str;
}
}
Custom Serializer 구현
public class StringPropertyMasker extends StdSerializer<String> implements ContextualSerializer {
private MaskingType maskingType;
protected StringPropertyMasker() {
super(String.class);
}
protected StringPropertyMasker(MaskingType maskingType) {
super(String.class);
this.maskingType = maskingType;
}
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeString(Masking.mask(maskingType, value));
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty property) {
if (property != null) {
Masked masked = property.getAnnotation(Masked.class);
if (masked != null) {
return new StringPropertyMasker(masked.type());
}
}
return this;
}
}
Custom Serializer Bean 주입
- java config 방식
@Configuration
public class CustomObjectMapper {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(String.class, new StringPropertyMasker());
objectMapper.registerModule(module);
return objectMapper;
}
}
- xml config 방식
<bean id="jacksonObjectMapper" class="me.choicore.config.CustomObjectMapper"/>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper"/>
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper"/>
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
사용 방법
public class Account {
@Masked(type = MaskingType.NAME)
private String username;
@Masked(type = MaskingType.CONTACT)
private String contact;
@Masked(type = MaskingType.CREDIT_CARD)
private String creditCard;
}
참조