Als ich es in Jackson serialisierte und protokollierte, wollte ich vertrauliche Daten wie Authentifizierungstoken zerstören und es einfach mit Anmerkungen angeben, also suchte ich.
Ersetzen Sie auf diese Weise die Eigenschaft im Feld POOJO durch "@ Sensitive" durch eine entsprechende Zeichenfolge:
@lombok.Value
public class SomeRequest {
/ ** Eigenschaften, die nicht ausgeblendet werden müssen * /
private final String userId;
/ ** Heikle Informationen * /
@Sensitive
private final String token;
}
Sie benötigen drei Klassen: eine Implementierung des Ersetzungsprozesses, eine Zuordnung zu den Anmerkungen, für die die Implementierung funktioniert, und ein Modul, das sie in ObjectMapper registriert.
Klassen, die mit Anmerkungen versehene Felder verarbeiten:
public class SensitiveFieldMaskingSerializer extends StdSerializer<Object> {
private static final long serialVersionUID = 3888199957574169748L;
protected SensitiveFieldMaskingSerializer() {
super(Object.class);
}
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
// Verarbeitung entsprechend ersetzen
if (value instanceof Number) {
gen.writeNumber(0);
} else if (value instanceof String) {
gen.writeString("Hidden: Sensitive string");
} else {
gen.writeNull();
}
}
}
Klasse, die die Annotation verknüpft, die die Implementierung von ↑ aufruft:
public class SensitiveFieldMaskingAnnotationIntrospector extends NopAnnotationIntrospector {
private static final long serialVersionUID = -4171975975956047379L;
@Override
public Object findSerializer(Annotated am) {
if (am.hasAnnotation(Sensitive.class)) {
return SensitiveFieldMaskingSerializer.class;
}
return null;
}
}
Verarbeitungsklasse zum Registrieren von ↑ in ObjectMapper:
static class SensitiveFieldMaskingModule extends Module {
@Override
public String getModuleName() {
return getClass().getSimpleName();
}
@Override
public Version version() {
return Version.unknownVersion();
}
@Override
public void setupModule(SetupContext context) {
context.insertAnnotationIntrospector(new SensitiveFieldMaskingAnnotationIntrospector());
}
}
Dies ist alles, was Sie implementieren müssen. Verwenden wir es also:
public final class Main {
public static void main(String[] args) throws Exception {
ObjectMapper logObjectMapper = new ObjectMapper()
.registerModule(new SensitiveFieldMaskingModule());
FooRequest fooRequest = new FooRequest ("Die, die Sie im Protokoll belassen können", "Die, die Sie nicht im Protokoll belassen können");
System.out.println ("Serialisierungsergebnis:" + logObjectMapper.writeValueAsString (fooRequest));
// Serialisierungsergebnis: {"userId": "Die, die Sie im Protokoll belassen können", "token": "Hidden: Sensitive string"}
System.out.println ("Konvertierung in Map:" + logObjectMapper.convertValue (fooRequest, Map.class));
// In Map konvertiert Ergebnis: {userId = Typ, den Sie im Protokoll belassen können, token = Hidden: Sensitive Zeichenfolge}
}
}
Sie können sehen, dass "Token" in beiden Ausgaben durch eine andere Zeichenfolge ersetzt wurde.
Ich habe es auch oben verlinkt, aber ich habe das, was den ganzen Weg funktioniert, auf den Punkt gebracht.
Wenn Sie einen ObjectMapper benötigen, der sich von dem normalen wie diesem unterscheidet, können Sie unnötige Probleme vermeiden, indem Sie ihn als neues Protokoll vorbereiten, anstatt den an anderer Stelle verwendeten ObjectMapper zu verwenden. Wenn Sie einen DI-Container verwenden, stören Sie ihn nicht und definieren Sie ihn als benannte Bean.
Recommended Posts