sl4fj와 유사한 일반적인 문자열 대체 기능이 있습니까?


85

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
아래 답변을 주신 분들께 감사드립니다. 또한,이 질문이 이미 여기에서 요청되었음을 발견했습니다 : stackoverflow.com/questions/3114021 . 다소 중복을 게시하여 죄송합니다.
kmccoy

답변:


113

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

45

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

1
MessageFormat은 매우 다양하고 강력하지만 간단한 대체의 경우 String.format이 더 간단하고 덜 제한적일 수 있습니다 (예 : MessageFormat은 작은 따옴표를 두 배로해야 함).
Kat

1
new Integer (1) 위의 1로만 대체되면 역시 작동합니다.
TechnoCrat

25

문자열의 여러 변수를 값으로 대체 할 수있는 솔루션을 찾고 있다면 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);

일반적으로 허용되는 패턴을 따르며 변수가있는 맵을 해결되지 않은 문자열과 함께 값에 전달할 수 있으며 해결 된 문자열을 반환합니다.


20

org.slf4j.helpers.MessageFormatter 를 사용하는 것이 좋습니다 . 그것의 도움으로 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); 
}

참고 : 배열의 마지막 개체가 Exception이면 slf4j 로거와 마찬가지로 메시지에서 대체되지 않습니다. 예외는를 통해 액세스 할 수 있습니다 MessageFormatter.arrayFormat(msg, objs).getThrowable().


3
나는 이것이 좋은 범용 대답은 아니지만 실제로는 요청 된 것의 지점에 있다고 주장합니다.
마이클 Piefel

3
나는 이것이 정답이라고 생각합니다. 이것은 성능면에서 최고입니다.
Sasa

1
질문이 요청한 정확한 구문을 사용하므로 최상의 답변입니다.
Christoph

솔직히 IMHO 는 원래 질문과 실제로 일치 하는 유일한 답변입니다 ... 왜 지금 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을 참조하십시오.

교체 가능한 각 토큰과 매개 변수를 나타내는 '{}'를 포함하는 형식 문자열로 구성된 메시지를 처리합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.