Reputation: 5445
Can I limit a string length and add "..." to the end if the string was truncated, without using the
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));
}
This is for logging purposes. SLF4j solutions might work, but I'd rather keep it core Java.
Already checked out Limiting the number of characters in a string, and chopping off the rest and related questions.
Upvotes: 2
Views: 2499
Reputation: 2022
This is not core Java, but if you are using Apache commons lang, you can use StringUtils abbreviate method.
Sample code:
@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());
}
Upvotes: 0
Reputation: 298113
It’s not clear when the SLF4J API will catch up, but the Java 8 core API allows to defer any potentially expensive calculation to the point after the logging level has been checked, so it does not happen if the particular level is not 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? "": "..."));
}
}
}
Note that when LIMIT
is a compile-time constant, "RESPONSE: %."+LIMIT+"s%s"
is a compile-time constant too, hence, there is no need to manually inline the number, so using a named constant ensures consistency between the formatting string and the conditional.
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...
The following program demonstrates that the calculation does not happen, once the log level forbids it:
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);
}
Upvotes: 2
Reputation: 718708
Here's one way
public String shorten(String s, int max) {
if (s != null && s.length() > max) {
s = s.substring(0, max - 3) + "...";
return s;
}
Note that this can break if the string that you are shortening includes characters that are not in the BMP.
(I wouldn't normally do a null
test there, but your use-case requires it.)
Then ...
log.trace("RESPONSE: {}", shorten(responseContent, 1000);
... except that you should now guard the trace call to avoid unnecessary calls to shorten
.
Upvotes: 2