Есть ли общая функция замены строк, аналогичная sl4fj?
С sl4fj, если я хочу построить строковое сообщение, есть хороший подход, который использует подстановки. Например, это может быть что-то вроде:
logger.info("Action {} occured on object {}.", objectA.getAction(), objectB);
Если требуется более нескольких замен, то это что-то вроде:
logger.info("Action {} occured on object {} with outcome {}.",
new Object[]{objectA.getAction(), objectB, outcome});
Мой вопрос: есть ли общий способ для меня создать строку (а не только сообщение журнала slf4j)? Что-то вроде:
String str = someMethod("Action {} occured on object {}.", objectA.getAction(), objectB);
или
String str = someMethod("Action {} occured on object {} with outcome {}.",
new Object[]{objectA.getAction(), objectB, outcome});
Если это в стандартной библиотеке Java, что бы это означало "someMethod"?
Спасибо.
Ответы
Ответ 1
String.format
String str = String.format("Action %s occured on object %s.",
objectA.getAction(), objectB);
или
String str = String.format("Action %s occured on object %s with outcome %s.",
new Object[]{objectA.getAction(), objectB, outcome});
Вы также можете использовать числовые позиции, например, для переключения параметров вокруг:
String str = String.format("Action %2$s occured on object %1$s.",
objectA.getAction(), objectB);
Ответ 2
Вы можете использовать String.format или MessageFormat.format
Например,
MessageFormat.format("A sample value {1} with a sample string {0}",
new Object[] {"first", 1});
или просто
MessageFormat.format("A sample value {1} with a sample string {0}", "first", 1);
Ответ 3
Если вы ищете решение, в котором вы можете заменить кучу переменных в String со значениями, вы можете использовать StrSubstitutor.
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);
Это следует общепринятому шаблону, в котором можно передать карту с переменными значениями вместе с неразрешенной строкой и возвращает разрешенную строку.
Ответ 4
Я бы предложил использовать org.slf4j.helpers.MessageFormatter. С его помощью можно создать метод utillity, который использует тот же стиль форматирования, что и slf4j:
// 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);
}
Примечание. Если последний объект в массиве является Исключением, он не будет заменен в сообщении, как с помощью регистратора slf4j. Исключение будет доступно через MessageFormatter.arrayFormat(msg, objs).getThrowable()
.
Ответ 5
Я выбираю wrap the Log4j2 ParameterizedMessage, который был первоначально написан для Лилит Джоерном Хукхорном:
public static String format(final String messagePattern, Object... arguments) {
return ParameterizedMessage.format(messagePattern, arguments);
}
В центре внимания - формат сообщений, в отличие от SLF4J MessageFormatter, который содержит ненужную обработку Throwable.
См. Javadoc:
Обрабатывает сообщения, которые состоят из строки формата, содержащей '{}' для представления каждого сменного токена и параметров.