GH-9369: Fix MutableMessageHeaders for serialization

Fixes: #9369

* Implement `MutableMessageHeaders.readResolve()` to reinstate the instance

(cherry picked from commit 02b58277f4)
This commit is contained in:
Mitchell
2024-08-09 05:16:49 +12:00
committed by Spring Builds
parent 7238432c83
commit 2c47b2b6fa
2 changed files with 45 additions and 0 deletions

View File

@@ -16,6 +16,8 @@
package org.springframework.integration.support;
import java.io.ObjectStreamException;
import java.io.Serial;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.UUID;
@@ -32,6 +34,7 @@ import org.springframework.messaging.MessageHeaders;
* @author David Turanski
* @author Artem Bilan
* @author Nathan Kurtyka
* @author Mitchell McDonald
*
* @since 4.2
*/
@@ -74,6 +77,11 @@ public class MutableMessageHeaders extends MessageHeaders {
return super.getRawHeaders().remove(key);
}
@Serial
private Object readResolve() throws ObjectStreamException {
return new MutableMessageHeaders(this);
}
@Nullable
private static UUID extractId(@Nullable Map<String, Object> headers) {
if (headers != null && headers.containsKey(MessageHeaders.ID)) {

View File

@@ -16,6 +16,11 @@
package org.springframework.integration.support;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
@@ -26,11 +31,13 @@ import org.junit.Test;
import org.springframework.messaging.MessageHeaders;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
/**
* @author Stuart Williams
* @author Nathan Kurtyka
* @author Mitchell McDonald
*
* @since 4.2
*/
@@ -105,4 +112,34 @@ public class MutableMessageTests {
assertThat(mutableMessageBytes.getHeaders().getTimestamp()).isEqualTo(timestamp);
}
@Test
public void testMessageHeaderIsSerializableAndDeserializableWithNonSerializableValues()
throws IOException, ClassNotFoundException {
String payload = "payload";
Map<String, Object> headerMap = new HashMap<>();
headerMap.put("header1", "serializableValue");
headerMap.put("header2", new Object()); // Non-Serializable value
MutableMessage<String> mutableMessage = new MutableMessage<>(payload, headerMap);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
outputStream.writeObject(mutableMessage);
outputStream.flush();
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
ObjectInputStream inputStream = new ObjectInputStream(byteArrayInputStream);
Object deserializedObject = inputStream.readObject();
assertThat(deserializedObject).isInstanceOf(MutableMessage.class);
MutableMessage<?> deserializedMessage =
(MutableMessage<?>) deserializedObject;
assertThat(deserializedMessage.getHeaders().get("header2")).isNull(); // Non-serializable value removed
assertThat(deserializedMessage.getHeaders().get("header1")).isEqualTo("serializableValue");
assertThatNoException().isThrownBy(() -> deserializedMessage.getRawHeaders().put("header3", "newValue"));
}
}