Skip to content

Instantly share code, notes, and snippets.

@ufuk
Created April 20, 2017 11:37
Show Gist options
  • Save ufuk/481c02a0694f654167eb00116be02cac to your computer and use it in GitHub Desktop.
Save ufuk/481c02a0694f654167eb00116be02cac to your computer and use it in GitHub Desktop.
JSON serializing with masking support...
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair;
public final class LoggingObjectMapper extends ObjectMapper {
private static final long serialVersionUID = -1620079742091329228L;
public LoggingObjectMapper() {
super();
MaskBeforeLogAnnotationIntrospector maskBeforeLogAnnotationIntrospector = new MaskBeforeLogAnnotationIntrospector();
AnnotationIntrospector pair = AnnotationIntrospectorPair.pair(this.getSerializationConfig().getAnnotationIntrospector(), maskBeforeLogAnnotationIntrospector);
this.setAnnotationIntrospector(pair);
}
public String toJsonString(Object value) {
if (value == null) {
return null;
}
try {
return writeValueAsString(value);
} catch (Exception e) {
return "Object couldn't be converted to JSON: " + e.getMessage();
}
}
}
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)
public @interface MaskBeforeLog {
int leftVisible() default 0;
int rightVisible() default 0;
}
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector;
public class MaskBeforeLogAnnotationIntrospector extends NopAnnotationIntrospector {
private static final long serialVersionUID = 2345739318451076683L;
@Override
public Object findSerializer(Annotated annotated) {
MaskBeforeLog annotation = annotated.getAnnotation(MaskBeforeLog.class);
if (annotation != null) {
return new MaskingSerializer(annotation.leftVisible(), annotation.rightVisible());
}
return null;
}
}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
public class MaskingSerializer extends StdSerializer<String> {
private static final long serialVersionUID = 5586926178824899685L;
@Getter
private int leftVisible;
@Getter
private int rightVisible;
public MaskingSerializer(int leftVisible, int rightVisible) {
super(String.class);
this.leftVisible = leftVisible;
this.rightVisible = rightVisible;
}
@Override
public void serialize(String value, JsonGenerator generator, SerializerProvider provider) throws IOException {
if (isSuitableForMasking(value)) {
generator.writeString(MaskUtils.mask(value, leftVisible, rightVisible));
} else {
generator.writeString(value);
}
}
private boolean isSuitableForMasking(String value) {
if (StringUtils.isNotBlank(value)) {
int visibleCharacterCount = leftVisible + rightVisible;
return value.length() > visibleCharacterCount;
}
return false;
}
}
import org.apache.commons.lang3.StringUtils;
public final class MaskUtils {
private MaskUtils() {
}
public static String maskCardNumber(String cardNumber) {
return mask(cardNumber, 6, 4);
}
public static String mask(String cardNumber, int showFirstDigitCount, int showLastDigitCount) {
String leftPart = StringUtils.left(cardNumber, showFirstDigitCount);
String maskedPart = StringUtils.repeat("*", cardNumber.length() - (showFirstDigitCount + showLastDigitCount));
String rightPart = StringUtils.right(cardNumber, showLastDigitCount);
return leftPart + maskedPart + rightPart;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment