Skip to content

Commit 74bdcd8

Browse files
committed
MutableMessageHeaders serializes itself as regular MessageHeaders
Issue: SPR-15262
1 parent 692e432 commit 74bdcd8

File tree

2 files changed

+48
-54
lines changed

2 files changed

+48
-54
lines changed

spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -136,19 +136,15 @@ public class MessageHeaderAccessor {
136136
* A constructor to create new headers.
137137
*/
138138
public MessageHeaderAccessor() {
139-
this.headers = new MutableMessageHeaders();
139+
this(null);
140140
}
141141

142142
/**
143143
* A constructor accepting the headers of an existing message to copy.
144+
* @param message a message to copy the headers from, or {@code null} if none
144145
*/
145146
public MessageHeaderAccessor(Message<?> message) {
146-
if (message != null) {
147-
this.headers = new MutableMessageHeaders(message.getHeaders());
148-
}
149-
else {
150-
this.headers = new MutableMessageHeaders();
151-
}
147+
this.headers = new MutableMessageHeaders(message != null ? message.getHeaders() : null);
152148
}
153149

154150

@@ -193,7 +189,6 @@ public void setLeaveMutable(boolean leaveMutable) {
193189
* @since 4.1
194190
*/
195191
public void setImmutable() {
196-
this.headers.setIdAndTimestamp();
197192
this.headers.setImmutable();
198193
}
199194

@@ -583,7 +578,7 @@ public static <T extends MessageHeaderAccessor> T getAccessor(
583578

584579
if (messageHeaders instanceof MutableMessageHeaders) {
585580
MutableMessageHeaders mutableHeaders = (MutableMessageHeaders) messageHeaders;
586-
MessageHeaderAccessor headerAccessor = mutableHeaders.getMessageHeaderAccessor();
581+
MessageHeaderAccessor headerAccessor = mutableHeaders.getAccessor();
587582
if (requiredType.isAssignableFrom(headerAccessor.getClass())) {
588583
return (T) headerAccessor;
589584
}
@@ -603,7 +598,7 @@ public static <T extends MessageHeaderAccessor> T getAccessor(
603598
public static MessageHeaderAccessor getMutableAccessor(Message<?> message) {
604599
if (message.getHeaders() instanceof MutableMessageHeaders) {
605600
MutableMessageHeaders mutableHeaders = (MutableMessageHeaders) message.getHeaders();
606-
MessageHeaderAccessor accessor = mutableHeaders.getMessageHeaderAccessor();
601+
MessageHeaderAccessor accessor = mutableHeaders.getAccessor();
607602
if (accessor != null) {
608603
return (accessor.isMutable() ? accessor : accessor.createAccessor(message));
609604
}
@@ -615,38 +610,23 @@ public static MessageHeaderAccessor getMutableAccessor(Message<?> message) {
615610
@SuppressWarnings("serial")
616611
private class MutableMessageHeaders extends MessageHeaders {
617612

618-
private boolean immutable;
619-
620-
public MutableMessageHeaders() {
621-
this(null);
622-
}
613+
private boolean mutable = true;
623614

624615
public MutableMessageHeaders(Map<String, Object> headers) {
625616
super(headers, MessageHeaders.ID_VALUE_NONE, -1L);
626617
}
627618

628-
public MessageHeaderAccessor getMessageHeaderAccessor() {
629-
return MessageHeaderAccessor.this;
630-
}
631-
632619
@Override
633620
public Map<String, Object> getRawHeaders() {
634-
Assert.state(!this.immutable, "Already immutable");
621+
Assert.state(this.mutable, "Already immutable");
635622
return super.getRawHeaders();
636623
}
637624

638625
public void setImmutable() {
639-
this.immutable = true;
640-
}
641-
642-
public boolean isMutable() {
643-
return !this.immutable;
644-
}
645-
646-
public void setIdAndTimestamp() {
647-
if (!isMutable()) {
626+
if (!this.mutable) {
648627
return;
649628
}
629+
650630
if (getId() == null) {
651631
IdGenerator idGenerator = (MessageHeaderAccessor.this.idGenerator != null ?
652632
MessageHeaderAccessor.this.idGenerator : MessageHeaders.getIdGenerator());
@@ -655,11 +635,27 @@ public void setIdAndTimestamp() {
655635
getRawHeaders().put(ID, id);
656636
}
657637
}
638+
658639
if (getTimestamp() == null) {
659640
if (MessageHeaderAccessor.this.enableTimestamp) {
660641
getRawHeaders().put(TIMESTAMP, System.currentTimeMillis());
661642
}
662643
}
644+
645+
this.mutable = false;
646+
}
647+
648+
public boolean isMutable() {
649+
return this.mutable;
650+
}
651+
652+
public MessageHeaderAccessor getAccessor() {
653+
return MessageHeaderAccessor.this;
654+
}
655+
656+
protected Object writeReplace() {
657+
// Serialize as regular MessageHeaders (without MessageHeaderAccessor reference)
658+
return new MessageHeaders(this);
663659
}
664660
}
665661

spring-messaging/src/test/java/org/springframework/messaging/support/MessageHeaderAccessorTests.java

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,10 +17,8 @@
1717
package org.springframework.messaging.support;
1818

1919
import java.nio.charset.StandardCharsets;
20-
import java.util.Arrays;
2120
import java.util.Collections;
2221
import java.util.HashMap;
23-
import java.util.HashSet;
2422
import java.util.Map;
2523
import java.util.UUID;
2624

@@ -30,8 +28,8 @@
3028

3129
import org.springframework.messaging.Message;
3230
import org.springframework.messaging.MessageHeaders;
33-
import org.springframework.util.IdGenerator;
3431
import org.springframework.util.MimeTypeUtils;
32+
import org.springframework.util.SerializationTestUtils;
3533

3634
import static org.hamcrest.CoreMatchers.*;
3735
import static org.junit.Assert.*;
@@ -166,7 +164,7 @@ public void copyHeadersFromNullMap() {
166164
headers.copyHeadersIfAbsent(null);
167165

168166
assertEquals(1, headers.getMessageHeaders().size());
169-
assertEquals(new HashSet<>(Arrays.asList("id")), headers.getMessageHeaders().keySet());
167+
assertEquals(Collections.singleton("id"), headers.getMessageHeaders().keySet());
170168
}
171169

172170
@Test
@@ -280,12 +278,7 @@ public void timestampDefaultBehavior() {
280278
public void idGeneratorCustom() {
281279
final UUID id = new UUID(0L, 23L);
282280
MessageHeaderAccessor accessor = new MessageHeaderAccessor();
283-
accessor.setIdGenerator(new IdGenerator() {
284-
@Override
285-
public UUID generateId() {
286-
return id;
287-
}
288-
});
281+
accessor.setIdGenerator(() -> id);
289282
assertSame(id, accessor.getMessageHeaders().getId());
290283
}
291284

@@ -299,12 +292,7 @@ public void idGeneratorDefaultBehavior() {
299292
@Test
300293
public void idTimestampWithMutableHeaders() {
301294
MessageHeaderAccessor accessor = new MessageHeaderAccessor();
302-
accessor.setIdGenerator(new IdGenerator() {
303-
@Override
304-
public UUID generateId() {
305-
return MessageHeaders.ID_VALUE_NONE;
306-
}
307-
});
295+
accessor.setIdGenerator(() -> MessageHeaders.ID_VALUE_NONE);
308296
accessor.setEnableTimestamp(false);
309297
accessor.setLeaveMutable(true);
310298
MessageHeaders headers = accessor.getMessageHeaders();
@@ -313,12 +301,7 @@ public UUID generateId() {
313301
assertNull(headers.getTimestamp());
314302

315303
final UUID id = new UUID(0L, 23L);
316-
accessor.setIdGenerator(new IdGenerator() {
317-
@Override
318-
public UUID generateId() {
319-
return id;
320-
}
321-
});
304+
accessor.setIdGenerator(() -> id);
322305
accessor.setEnableTimestamp(true);
323306
accessor.setImmutable();
324307

@@ -396,10 +379,25 @@ public String toString() {
396379
assertEquals("headers={contentType=text/plain} payload=" + sb + " > 80", actual);
397380
}
398381

382+
@Test
383+
public void serializeMutableHeaders() throws Exception {
384+
Map<String, Object> headers = new HashMap<>();
385+
headers.put("foo", "bar");
386+
Message<String> message = new GenericMessage<>("test", headers);
387+
MessageHeaderAccessor mutableAccessor = MessageHeaderAccessor.getMutableAccessor(message);
388+
mutableAccessor.setContentType(MimeTypeUtils.TEXT_PLAIN);
389+
390+
message = new GenericMessage<>(message.getPayload(), mutableAccessor.getMessageHeaders());
391+
Message<?> output = (Message<?>) SerializationTestUtils.serializeAndDeserialize(message);
392+
assertEquals("test", output.getPayload());
393+
assertEquals("bar", output.getHeaders().get("foo"));
394+
assertNotNull(output.getHeaders().get(MessageHeaders.CONTENT_TYPE));
395+
}
396+
399397

400398
public static class TestMessageHeaderAccessor extends MessageHeaderAccessor {
401399

402-
private TestMessageHeaderAccessor() {
400+
public TestMessageHeaderAccessor() {
403401
}
404402

405403
private TestMessageHeaderAccessor(Message<?> message) {

0 commit comments

Comments
 (0)