Skip to content

Commit

Permalink
Message toString() Improvement
Browse files Browse the repository at this point in the history
Don't convert large message bodies to a `String` in `toString()`.

Set a limit (50) that can be modified by users.

Avoid possible OOM Errors.

**cherry-pick to 2.3.x, 2.2.x**

# Conflicts:
#	spring-amqp/src/main/java/org/springframework/amqp/core/Message.java
  • Loading branch information
garyrussell authored and artembilan committed Nov 10, 2021
1 parent 14f993f commit bde294d
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ public class Message implements Serializable {

private static final String DEFAULT_ENCODING = Charset.defaultCharset().name();

private static final int DEFAULT_MAX_BODY_LENGTH = 50;

private static String bodyEncoding = DEFAULT_ENCODING;

private static int maxBodyLength = DEFAULT_MAX_BODY_LENGTH;

private final MessageProperties messageProperties;

private final byte[] body;
Expand Down Expand Up @@ -91,6 +95,16 @@ public static void setDefaultEncoding(String encoding) {
bodyEncoding = encoding;
}

/**
* Set the maximum length of a test message body to render as a String in
* {@link #toString()}. Default 50.
* @param length the length to render.
* @since 2.2.20
*/
public static void setMaxBodyLength(int length) {
maxBodyLength = length;
}

public byte[] getBody() {
return this.body; //NOSONAR
}
Expand Down Expand Up @@ -120,10 +134,11 @@ private String getBodyContentAsString() {
return "[serialized object]";
}
String encoding = encoding(nullProps);
if (MessageProperties.CONTENT_TYPE_TEXT_PLAIN.equals(contentType)
if (this.body.length <= maxBodyLength
&& (MessageProperties.CONTENT_TYPE_TEXT_PLAIN.equals(contentType)
|| MessageProperties.CONTENT_TYPE_JSON.equals(contentType)
|| MessageProperties.CONTENT_TYPE_JSON_ALT.equals(contentType)
|| MessageProperties.CONTENT_TYPE_XML.equals(contentType)) {
|| MessageProperties.CONTENT_TYPE_XML.equals(contentType))) {
return new String(this.body, encoding);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Date;
import java.util.stream.IntStream;

import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -110,6 +111,24 @@ public void fooNotDeserialized() {
assertThat(listMessage.toString()).contains("[serialized object]");
}

@Test
void dontToStringLongBody() {
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN);
StringBuilder builder1 = new StringBuilder();
IntStream.range(0, 50).forEach(i -> builder1.append("x"));
String bodyAsString = builder1.toString();
Message message = new Message(bodyAsString.getBytes(), messageProperties);
assertThat(message.toString()).contains(bodyAsString);
StringBuilder builder2 = new StringBuilder();
IntStream.range(0, 51).forEach(i -> builder2.append("x"));
bodyAsString = builder2.toString();
message = new Message(bodyAsString.getBytes(), messageProperties);
assertThat(message.toString()).contains("[51]");
Message.setMaxBodyLength(100);
assertThat(message.toString()).contains(bodyAsString);
}

@SuppressWarnings("serial")
public static class Foo implements Serializable {

Expand Down

0 comments on commit bde294d

Please sign in to comment.