限制字符串长度并添加" ..."如果被截断

时间:2017-01-27 11:12:50

标签: string java-8

我可以限制字符串长度并添加" ..."如果字符串被截断,则不使用

if ... else ...

String responseContent = response.getContent();
if (responseContent == null || responseContent.length() <= 1000) {
    log.finest(String.format("RESPONSE: %s", responseContent));
} else {
    log.finest(String.format("RESPONSE: %.999s ...", responseContent));
}

这是用于记录目的。 SLF4j解决方案可能有效,但我宁愿将其保留为核心Java。

已检出Limiting the number of characters in a string, and chopping off the rest及相关问题。

3 个答案:

答案 0 :(得分:2)

这是单程

public String shorten(String s, int max) {
    if (s != null && s.length() > max) {
        s = s.substring(0, max - 3) + "...";
    return s;
}

请注意,如果您缩短的字符串包含不在BMP中的字符,则会中断。

(我通常不会在那里进行null测试,但您的用例需要它。)

然后......

log.trace("RESPONSE: {}", shorten(responseContent, 1000);

...除了您现在应该保护跟踪调用以避免对shorten进行不必要的调用。

答案 1 :(得分:2)

目前尚不清楚SLF4J API何时会赶上,但Java 8核心API允许将任何可能昂贵的计算推迟到检查日志记录级别之后,因此如果特定级别不可记录则不会发生:

import java.util.logging.Logger;

public class LogAbbr {
    final static int LIMIT = 15;
    public static void main(String[] args) {
        Logger log=Logger.getAnonymousLogger();
        String[] examples={"short string", "rather long string"};
        for(String responseContent: examples) {
            log.info(() -> String.format("RESPONSE: %."+LIMIT+"s%s",
                responseContent, responseContent.length()<=LIMIT? "": "..."));
        }
    }
}

注意,当LIMIT是编译时常量时,"RESPONSE: %."+LIMIT+"s%s"也是编译时常量,因此,不需要手动内联数字,因此使用命名常量可确保一致性格式化字符串和条件之间。

Demo on Ideone

Jan 27, 2017 11:53:20 AM Ideone main
INFO: RESPONSE: short string
Jan 27, 2017 11:53:20 AM Ideone main
INFO: RESPONSE: rather long str...

以下程序演示了一旦日志级别禁止计算,就不会发生计算:

Logger log=Logger.getAnonymousLogger();
String[] examples={"short string", "rather long string"};
for(String responseContent: examples) {
    log.info(() -> {
        System.out.println("Potentially expensive operation with "+responseContent);
        return responseContent;
    });
    log.setLevel(Level.SEVERE);
}

Demo on Ideone

答案 2 :(得分:0)

这不是 core Java,但如果您使用的是Apache commons lang,则可以使用StringUtils abbreviate method

示例代码:

@Test
public void abbrevTest(){
    String longStr = StringUtils.repeat("a", 100);
    String abbreviate = StringUtils.abbreviate(longStr, 50);
    Assert.assertTrue(StringUtils.endsWith(abbreviate, "..."));
    Assert.assertEquals(50, abbreviate.length());
    String shortStr = StringUtils.repeat("a", 10);
    String shortAbbrev = StringUtils.abbreviate(shortStr, 50);
    Assert.assertTrue(StringUtils.endsWith(shortAbbrev, "a"));
    Assert.assertEquals(10, shortAbbrev.length());
}