Есть ли общая функция замены строк, аналогичная 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:

Обрабатывает сообщения, которые состоят из строки формата, содержащей '{}' для представления каждого сменного токена и параметров.