Skip to content

Commit bde294d

Browse files
garyrussellartembilan
authored andcommitted
Message toString() Improvement
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
1 parent 14f993f commit bde294d

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

spring-amqp/src/main/java/org/springframework/amqp/core/Message.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ public class Message implements Serializable {
4343

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

46+
private static final int DEFAULT_MAX_BODY_LENGTH = 50;
47+
4648
private static String bodyEncoding = DEFAULT_ENCODING;
4749

50+
private static int maxBodyLength = DEFAULT_MAX_BODY_LENGTH;
51+
4852
private final MessageProperties messageProperties;
4953

5054
private final byte[] body;
@@ -91,6 +95,16 @@ public static void setDefaultEncoding(String encoding) {
9195
bodyEncoding = encoding;
9296
}
9397

98+
/**
99+
* Set the maximum length of a test message body to render as a String in
100+
* {@link #toString()}. Default 50.
101+
* @param length the length to render.
102+
* @since 2.2.20
103+
*/
104+
public static void setMaxBodyLength(int length) {
105+
maxBodyLength = length;
106+
}
107+
94108
public byte[] getBody() {
95109
return this.body; //NOSONAR
96110
}
@@ -120,10 +134,11 @@ private String getBodyContentAsString() {
120134
return "[serialized object]";
121135
}
122136
String encoding = encoding(nullProps);
123-
if (MessageProperties.CONTENT_TYPE_TEXT_PLAIN.equals(contentType)
137+
if (this.body.length <= maxBodyLength
138+
&& (MessageProperties.CONTENT_TYPE_TEXT_PLAIN.equals(contentType)
124139
|| MessageProperties.CONTENT_TYPE_JSON.equals(contentType)
125140
|| MessageProperties.CONTENT_TYPE_JSON_ALT.equals(contentType)
126-
|| MessageProperties.CONTENT_TYPE_XML.equals(contentType)) {
141+
|| MessageProperties.CONTENT_TYPE_XML.equals(contentType))) {
127142
return new String(this.body, encoding);
128143
}
129144
}

spring-amqp/src/test/java/org/springframework/amqp/core/MessageTests.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.nio.charset.StandardCharsets;
2727
import java.util.Collections;
2828
import java.util.Date;
29+
import java.util.stream.IntStream;
2930

3031
import org.junit.jupiter.api.Test;
3132

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

114+
@Test
115+
void dontToStringLongBody() {
116+
MessageProperties messageProperties = new MessageProperties();
117+
messageProperties.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN);
118+
StringBuilder builder1 = new StringBuilder();
119+
IntStream.range(0, 50).forEach(i -> builder1.append("x"));
120+
String bodyAsString = builder1.toString();
121+
Message message = new Message(bodyAsString.getBytes(), messageProperties);
122+
assertThat(message.toString()).contains(bodyAsString);
123+
StringBuilder builder2 = new StringBuilder();
124+
IntStream.range(0, 51).forEach(i -> builder2.append("x"));
125+
bodyAsString = builder2.toString();
126+
message = new Message(bodyAsString.getBytes(), messageProperties);
127+
assertThat(message.toString()).contains("[51]");
128+
Message.setMaxBodyLength(100);
129+
assertThat(message.toString()).contains(bodyAsString);
130+
}
131+
113132
@SuppressWarnings("serial")
114133
public static class Foo implements Serializable {
115134

0 commit comments

Comments
 (0)