自定义Jackson ObjectMapper以读取自定义注释和带注释的蒙版字段
问题描述:
在创建自定义批注@MaskSensitiveData时,我有一个要求.我注释敏感字段.喜欢
I have a requirement where I have created a Custom Annotation @MaskSensitiveData. I annotate sensitive fields. like
class MyBean {
String userName;
@MaskSensitiveData
String cardNumber;
String abc;
String xyz;
}
ObjectMapper mapper = new ObjectMapper();
String json = null;
AnnotationIntrospector primary = new JaxbAnnotationIntrospector();
AnnotationIntrospector secondary = new JacksonAnnotationIntrospector();
AnnotationIntrospector pair = new AnnotationIntrospectorPair(primary, secondary);
mapper.setAnnotationIntrospector(pair);
try {
json = mapper.writeValueAsString(obj);
/*
* if(json != null ) { json = getLoggableString(json); }
*/
} catch (Exception e) {
return "Unable to convert to Json object:" + obj.toString() + " Message: " + e.getMessage();
}
我正在使用Jackson ObjectMapper将objct转换为Json之类. 我需要自定义对象映射器以屏蔽返回json中的cardNumber字段. 请提出一个更好的方法.
I am using Jackson ObjectMapper to convert objct to Json like. I need to customize Object Mapper to mask cardNumber field in return json. Please suggest a better way.
答
以下是使用自定义JsonSerializer解决您的问题的方法. 从此博客文章中遵循步骤.
Here is a solution to your problem using custom JsonSerializer. Steps are followed from this blog post.
创建自定义序列化器
public class MaskingSerializer extends JsonSerializer < MyBean > {
@
Override
public void serialize(MyBean value, JsonGenerator jGen, SerializerProvider serializers) throws IOException, JsonProcessingException {
jGen.writeStartObject();
Field[] fields = value.getClass().getDeclaredFields();
for (Field field: fields) {
field.setAccessible(true);
MaskSensitiveData mask = field.getDeclaredAnnotation(MaskSensitiveData.class);
try {
if (mask != null) {
field.setAccessible(true);
field.set(value, field.get(value).toString().replaceAll(".", "*"));
}
jGen.writeStringField(field.getName(), field.get(value).toString());
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
jGen.writeEndObject();
}
}
创建一个模块以捆绑序列化程序
public class MaskingModule extends SimpleModule {
private static final String NAME = "CustomIntervalModule";
private static final VersionUtil VERSION_UTIL = new VersionUtil() {};
public MaskingModule() {
super(NAME, VERSION_UTIL.version());
addSerializer(MyBean.class, new MaskingSerializer());
}
}
向ObjectMapper注册模块.
public class CustomObjectMapper extends ObjectMapper {
public CustomObjectMapper() {
registerModule(new MaskingModule());
}
}
测试代码
public class MyBeanTest {
private static final CustomObjectMapper OBJECT_MAPPER =
new CustomObjectMapper();
@Test
public void testIntervalSerialization() throws Exception {
MyBean mb = new MyBean();
mb.setAbc("value");
mb.setCardNumber("4441114443335551");
mb.setUserName("User");
mb.setXyz("value");
String result = OBJECT_MAPPER.writeValueAsString(mb);
System.out.println(result);
String expected = "{\"userName\":\"User\",\"cardNumber\":\"****************\",\"abc\":\"value\",\"xyz\":\"value\"}";
Assert.assertEquals(expected, result);
}
}