Estoy trabajando en una aplicación Java que maneja múltiples valores confidenciales. Estamos usando Lombok y tenemos muchas clases de datos que se ven así a continuación. Sin embargo, es confuso ver estas clases en el registro sin indicación de que contienen algunos campos críticos, ya que el toString generado ignorará al 100 % los campos excluidos. ¿Es posible que Lombok imprima algo como clientSecret=<HIDDEN> sin escribir un toString personalizado para cada clase?
/** data we will send to token endpoint */ @Data public class TokenReq { private String grantType; private String code; private String clientId; @ToString.Exclude private String refreshToken; @ToString.Exclude private String clientSecret; private String redirectUri; }Puede excluir el campo que debe enmascararse e incluir un método auxiliar que devuelva el valor enmascarado:
@Data public class TokenReq { @ToString.Exclude private String clientSecret; @ToString.Include(name="clientSecret") private String hiddenClientSecretForToString() { return "<HIDDEN>"; } }Como dije en el comentario, así es como lo hice hace un tiempo, probablemente necesite más trabajo, pero aquí está la idea:
interface ToString { default String innerToString(String... exclusions) { Method[] allMethods = getClass().getDeclaredMethods(); return Arrays.stream(allMethods) .filter(x -> x.getName().startsWith("get")) .map(x -> { if (Arrays.stream(exclusions).anyMatch(y -> ("get" + y).equalsIgnoreCase(x.getName()))) { return x.getName().substring(3) + " = <HIDDEN>"; } try { return x.getName().substring(3) + " = " + x.invoke(this); } catch (Exception e) { throw new RuntimeException(e); } }) .collect(Collectors.joining(" ")); } }Y una clase:
static class Person implements ToString { private String name; private String password; // constructor/getter or lombok annotations public String toString() { return innerToString("password"); } }Y luego el uso:
public static void main(String[] args) { Person p = new Person("eugene", "password"); System.out.println(p); }