是否有类似于sl4fj的通用字符串替换函数?

时间:2011-02-20 15:30:41

标签: java

如果我想构造一个字符串消息,那么使用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 个答案:

答案 0 :(得分:95)

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

答案 1 :(得分:38)

您可以使用String.formatMessageFormat.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);

答案 2 :(得分:22)

如果您正在寻找一个解决方案,您可以使用值替换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);

它遵循一个普遍接受的模式,其中可以将带有变量的映射与未解析的String一起传递给值,并返回已解析的字符串。

答案 3 :(得分:11)

我建议使用org.slf4j.helpers.MessageFormatter。在它的帮助下,可以创建一个使用与slf4j完全相同的格式样式的utillity方法:

// 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()访问例外。

答案 4 :(得分:0)

我选择包装最初由Joern Huxhorn为Lilith写的Log4j2 ParameterizedMessage

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

重点关注消息格式,与SLF4J MessageFormatter不同,后者包含对Throwable的不必要处理。

参见Javadoc:

  

处理由包含“{}”的格式字符串组成的消息,以表示每个可替换的令牌和参数。