2017-01-27 2 views
1

Могу ли я ограничить длину строки и добавить «...» до конца, если строка была обрезана, без использованияОграничение длины строки и добавление «...», если усеченный

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 и смежные вопросы.

+1

Если вы хотите «а держать его ядро ​​Java», следует учитывать, что не существует 'метод trace' в ядре Java регистраторе и' {} 'не поддерживается стандартный форматтер. – Holger

+0

Наша команда стандартизирована на SLF4J, но я бы предпочел не использовать ее. – Adam

+0

Я вижу, что вы говорите. Я отредактирую SLF4J '{}' в вопросе. – Adam

ответ

2

Непонятно, когда API SLF4J догонит, но API-интерфейс Java 8 core позволяет отложить любой потенциально дорогостоящий расчет до точки после проверки уровня ведения журнала, поэтому этого не происходит, если конкретный уровень не является loggable:

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:

+0

моя корпоративная платформа блокирует что-то на идеоне, но кажется, что ваш код записывает «», когда содержимое равно null, а не «RESPONSE:». Ограничение длины в константе -> +1 – Adam

+1

Нет, этот код генерирует исключение, если содержимое является «null». Вы должны изменить 'responseContent.length() <= LIMIT' на' responseContent == null || responseContent.length() <= LIMIT', чтобы исправить это. – Holger

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.

+0

Выглядит неплохо, возможно даже лучше, если называется 'shortenToMaxLen' – Adam

+0

Ваше последнее предложение является именно тем, почему я не думаю, что это должен быть принятый ответ. В противном случае +1 – Adam

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()); 
} 
Смежные вопросы