Skip to content

Commit 9834c42

Browse files
committed
MutableMessageHeaders serializes itself as regular MessageHeaders
Issue: SPR-15262 (cherry picked from commit 74bdcd8)
1 parent 7879bdf commit 9834c42

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.
@@ -135,19 +135,15 @@ public class MessageHeaderAccessor {
135135
* A constructor to create new headers.
136136
*/
137137
public MessageHeaderAccessor() {
138-
this.headers = new MutableMessageHeaders();
138+
this(null);
139139
}
140140

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

153149

@@ -192,7 +188,6 @@ public void setLeaveMutable(boolean leaveMutable) {
192188
* @since 4.1
193189
*/
194190
public void setImmutable() {
195-
this.headers.setIdAndTimestamp();
196191
this.headers.setImmutable();
197192
}
198193

@@ -582,7 +577,7 @@ public static <T extends MessageHeaderAccessor> T getAccessor(
582577

583578
if (messageHeaders instanceof MutableMessageHeaders) {
584579
MutableMessageHeaders mutableHeaders = (MutableMessageHeaders) messageHeaders;
585-
MessageHeaderAccessor headerAccessor = mutableHeaders.getMessageHeaderAccessor();
580+
MessageHeaderAccessor headerAccessor = mutableHeaders.getAccessor();
586581
if (requiredType.isAssignableFrom(headerAccessor.getClass())) {
587582
return (T) headerAccessor;
588583
}
@@ -602,7 +597,7 @@ public static <T extends MessageHeaderAccessor> T getAccessor(
602597
public static MessageHeaderAccessor getMutableAccessor(Message<?> message) {
603598
if (message.getHeaders() instanceof MutableMessageHeaders) {
604599
MutableMessageHeaders mutableHeaders = (MutableMessageHeaders) message.getHeaders();
605-
MessageHeaderAccessor accessor = mutableHeaders.getMessageHeaderAccessor();
600+
MessageHeaderAccessor accessor = mutableHeaders.getAccessor();
606601
if (accessor != null) {
607602
return (accessor.isMutable() ? accessor : accessor.createAccessor(message));
608603
}
@@ -614,38 +609,23 @@ public static MessageHeaderAccessor getMutableAccessor(Message<?> message) {
614609
@SuppressWarnings("serial")
615610
private class MutableMessageHeaders extends MessageHeaders {
616611

617-
private boolean immutable;
618-
619-
public MutableMessageHeaders() {
620-
this(null);
621-
}
612+
private boolean mutable = true;
622613

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

627-
public MessageHeaderAccessor getMessageHeaderAccessor() {
628-
return MessageHeaderAccessor.this;
629-
}
630-
631618
@Override
632619
public Map<String, Object> getRawHeaders() {
633-
Assert.state(!this.immutable, "Already immutable");
620+
Assert.state(this.mutable, "Already immutable");
634621
return super.getRawHeaders();
635622
}
636623

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

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.Charset;
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.*;
@@ -168,7 +166,7 @@ public void copyHeadersFromNullMap() {
168166
headers.copyHeadersIfAbsent(null);
169167

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

174172
@Test
@@ -282,12 +280,7 @@ public void timestampDefaultBehavior() {
282280
public void idGeneratorCustom() {
283281
final UUID id = new UUID(0L, 23L);
284282
MessageHeaderAccessor accessor = new MessageHeaderAccessor();
285-
accessor.setIdGenerator(new IdGenerator() {
286-
@Override
287-
public UUID generateId() {
288-
return id;
289-
}
290-
});
283+
accessor.setIdGenerator(() -> id);
291284
assertSame(id, accessor.getMessageHeaders().getId());
292285
}
293286

@@ -301,12 +294,7 @@ public void idGeneratorDefaultBehavior() {
301294
@Test
302295
public void idTimestampWithMutableHeaders() {
303296
MessageHeaderAccessor accessor = new MessageHeaderAccessor();
304-
accessor.setIdGenerator(new IdGenerator() {
305-
@Override
306-
public UUID generateId() {
307-
return MessageHeaders.ID_VALUE_NONE;
308-
}
309-
});
297+
accessor.setIdGenerator(() -> MessageHeaders.ID_VALUE_NONE);
310298
accessor.setEnableTimestamp(false);
311299
accessor.setLeaveMutable(true);
312300
MessageHeaders headers = accessor.getMessageHeaders();
@@ -315,12 +303,7 @@ public UUID generateId() {
315303
assertNull(headers.getTimestamp());
316304

317305
final UUID id = new UUID(0L, 23L);
318-
accessor.setIdGenerator(new IdGenerator() {
319-
@Override
320-
public UUID generateId() {
321-
return id;
322-
}
323-
});
306+
accessor.setIdGenerator(() -> id);
324307
accessor.setEnableTimestamp(true);
325308
accessor.setImmutable();
326309

@@ -398,10 +381,25 @@ public String toString() {
398381
assertEquals("headers={contentType=text/plain} payload=" + sb + " > 80", actual);
399382
}
400383

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

402400
public static class TestMessageHeaderAccessor extends MessageHeaderAccessor {
403401

404-
private TestMessageHeaderAccessor() {
402+
public TestMessageHeaderAccessor() {
405403
}
406404

407405
private TestMessageHeaderAccessor(Message<?> message) {

0 commit comments

Comments
 (0)