Существует ли общая функция подстановки строк, подобная 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"?

5 57

5 ответов:

строку.формат

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);

можно использовать строку.формат или MessageFormat.формат

например,

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);

Если вы ищете решение, в котором вы можете заменить кучу переменных в строке со значениями, вы можете использовать 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);

он следует общепринятому шаблону, где можно передать карту с переменными в значения вместе с неразрешенной строкой, и она возвращает разрешенную строку.

Я бы предложил использовать орг.slf4j.хелперов.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().

Я выбираю обернуть Log4j2 ParameterizedMessage который был первоначально написан для Лилит Йорном Хаксхорном:

public static String format(final String messagePattern, Object... arguments) {
    return ParameterizedMessage.format(messagePattern, arguments);
}

это фокус на формат сообщения, в отличие от SLF4J MessageFormatter который содержит ненужную обработку Throwable.

смотрите Javadoc:

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