Wenn ich mit sl4fj eine String-Nachricht erstellen möchte, gibt es einen guten Ansatz, bei dem Substitutionen verwendet werden. Zum Beispiel könnte es so etwas sein wie:
logger.info("Action {} occured on object {}.", objectA.getAction(), objectB);
Wenn mehr als ein paar Substitutionen erforderlich sind, ist es ungefähr so:
logger.info("Action {} occured on object {} with outcome {}.",
new Object[]{objectA.getAction(), objectB, outcome});
Meine Frage ist: Gibt es eine generische Möglichkeit für mich, eine Zeichenfolge zu erstellen (und nicht nur eine slf4j-Protokollnachricht)? Etwas wie:
String str = someMethod("Action {} occured on object {}.", objectA.getAction(), objectB);
oder
String str = someMethod("Action {} occured on object {} with outcome {}.",
new Object[]{objectA.getAction(), objectB, outcome});
Wenn es sich in der Standard-Java-Bibliothek befindet, was wäre diese "someMethod"?
Antworten:
String.format
String str = String.format("Action %s occured on object %s.", objectA.getAction(), objectB);
Oder
String str = String.format("Action %s occured on object %s with outcome %s.", new Object[]{objectA.getAction(), objectB, outcome});
Sie können auch numerische Positionen verwenden, um beispielsweise die Parameter umzuschalten:
String str = String.format("Action %2$s occured on object %1$s.", objectA.getAction(), objectB);
quelle
Sie können String.format oder MessageFormat.format verwenden
Z.B,
MessageFormat.format("A sample value {1} with a sample string {0}", new Object[] {"first", 1});
oder einfach
MessageFormat.format("A sample value {1} with a sample string {0}", "first", 1);
quelle
Wenn Sie nach einer Lösung suchen, bei der Sie eine Reihe von Variablen in einem String durch Werte ersetzen können, können Sie StrSubstitutor verwenden .
Map<String, String> valuesMap = new HashMap<>(); valuesMap.put("animal", "quick brown fox"); valuesMap.put("target", "lazy dog"); String templateString = "The ${animal} jumped over the ${target}."; StrSubstitutor sub = new StrSubstitutor(valuesMap); String resolvedString = sub.replace(templateString);
Es folgt einem allgemein akzeptierten Muster, bei dem eine Karte mit Variablen zusammen mit dem nicht aufgelösten String an Werte übergeben werden kann und ein aufgelöster String zurückgegeben wird.
quelle
Ich würde vorschlagen, org.slf4j.helpers.MessageFormatter zu verwenden . Mit seiner Hilfe kann eine Utillity-Methode erstellt werden, die genau den gleichen Formatierungsstil wie slf4j verwendet:
// utillity method to format like slf4j public static String format(String msg, Object... objs) { return MessageFormatter.arrayFormat(msg, objs).getMessage(); } // example usage public static void main(String[] args) { String msg = format("This msg is {} like slf{}j would do. {}", "formatted", 4, new Exception("Not substituted into the message")); // prints "This msg is formatted like slf4j would do. {}" System.out.println(msg); }
Hinweis : Wenn das letzte Objekt im Array eine Ausnahme ist, wird es nicht wie bei einem slf4j-Logger in der Nachricht ersetzt. Die Ausnahme wäre über zugänglich
MessageFormatter.arrayFormat(msg, objs).getThrowable()
.quelle
Ich wähle Wrap the Log4j2 ParameterizedMessage, die ursprünglich von Joern Huxhorn für Lilith geschrieben wurde:
public static String format(final String messagePattern, Object... arguments) { return ParameterizedMessage.format(messagePattern, arguments); }
Im Gegensatz zu SLF4J MessageFormatter, das eine unnötige Verarbeitung von Throwable enthält, liegt der Schwerpunkt auf dem Nachrichtenformat .
Siehe den Javadoc:
quelle