|
16 | 16 |
|
17 | 17 | package org.springframework.messaging.support;
|
18 | 18 |
|
| 19 | +import java.util.ArrayList; |
19 | 20 | import java.util.Collections;
|
20 | 21 | import java.util.LinkedList;
|
21 | 22 | import java.util.List;
|
@@ -75,6 +76,8 @@ protected NativeMessageHeaderAccessor(@Nullable Message<?> message) {
|
75 | 76 | @SuppressWarnings("unchecked")
|
76 | 77 | Map<String, List<String>> map = (Map<String, List<String>>) getHeader(NATIVE_HEADERS);
|
77 | 78 | if (map != null) {
|
| 79 | + // setHeader checks for equality but we need copy of native headers |
| 80 | + setHeader(NATIVE_HEADERS, null); |
78 | 81 | setHeader(NATIVE_HEADERS, new LinkedMultiValueMap<>(map));
|
79 | 82 | }
|
80 | 83 | }
|
@@ -103,38 +106,43 @@ public void setImmutable() {
|
103 | 106 | if (isMutable()) {
|
104 | 107 | Map<String, List<String>> map = getNativeHeaders();
|
105 | 108 | if (map != null) {
|
| 109 | + // setHeader checks for equality but we need immutable wrapper |
| 110 | + setHeader(NATIVE_HEADERS, null); |
106 | 111 | setHeader(NATIVE_HEADERS, Collections.unmodifiableMap(map));
|
107 | 112 | }
|
108 | 113 | super.setImmutable();
|
109 | 114 | }
|
110 | 115 | }
|
111 | 116 |
|
112 | 117 | @Override
|
113 |
| - public void setHeader(String name, @Nullable Object value) { |
114 |
| - if (name.equalsIgnoreCase(NATIVE_HEADERS)) { |
115 |
| - // Force removal since setHeader checks for equality |
116 |
| - super.setHeader(NATIVE_HEADERS, null); |
| 118 | + public void copyHeaders(@Nullable Map<String, ?> headersToCopy) { |
| 119 | + if (headersToCopy == null) { |
| 120 | + return; |
| 121 | + } |
| 122 | + |
| 123 | + @SuppressWarnings("unchecked") |
| 124 | + Map<String, List<String>> map = (Map<String, List<String>>) headersToCopy.get(NATIVE_HEADERS); |
| 125 | + if (map != null && map != getNativeHeaders()) { |
| 126 | + map.forEach(this::setNativeHeaderValues); |
117 | 127 | }
|
118 |
| - super.setHeader(name, value); |
| 128 | + |
| 129 | + // setHeader checks for equality, native headers should be equal by now |
| 130 | + super.copyHeaders(headersToCopy); |
119 | 131 | }
|
120 | 132 |
|
121 | 133 | @Override
|
122 |
| - @SuppressWarnings("unchecked") |
123 |
| - public void copyHeaders(@Nullable Map<String, ?> headersToCopy) { |
124 |
| - if (headersToCopy != null) { |
125 |
| - Map<String, List<String>> nativeHeaders = getNativeHeaders(); |
126 |
| - Map<String, List<String>> map = (Map<String, List<String>>) headersToCopy.get(NATIVE_HEADERS); |
127 |
| - if (map != null) { |
128 |
| - if (nativeHeaders != null) { |
129 |
| - nativeHeaders.putAll(map); |
130 |
| - } |
131 |
| - else { |
132 |
| - nativeHeaders = new LinkedMultiValueMap<>(map); |
133 |
| - } |
134 |
| - } |
135 |
| - super.copyHeaders(headersToCopy); |
136 |
| - setHeader(NATIVE_HEADERS, nativeHeaders); |
| 134 | + public void copyHeadersIfAbsent(@Nullable Map<String, ?> headersToCopy) { |
| 135 | + if (headersToCopy == null) { |
| 136 | + return; |
| 137 | + } |
| 138 | + |
| 139 | + @SuppressWarnings("unchecked") |
| 140 | + Map<String, List<String>> map = (Map<String, List<String>>) headersToCopy.get(NATIVE_HEADERS); |
| 141 | + if (map != null && getNativeHeaders() == null) { |
| 142 | + map.forEach(this::setNativeHeaderValues); |
137 | 143 | }
|
| 144 | + |
| 145 | + super.copyHeadersIfAbsent(headersToCopy); |
138 | 146 | }
|
139 | 147 |
|
140 | 148 | /**
|
@@ -201,6 +209,30 @@ public void setNativeHeader(String name, @Nullable String value) {
|
201 | 209 | }
|
202 | 210 | }
|
203 | 211 |
|
| 212 | + /** |
| 213 | + * Variant of {@link #addNativeHeader(String, String)} for all values. |
| 214 | + * @since 5.2.12 |
| 215 | + */ |
| 216 | + public void setNativeHeaderValues(String name, @Nullable List<String> values) { |
| 217 | + Assert.state(isMutable(), "Already immutable"); |
| 218 | + Map<String, List<String>> map = getNativeHeaders(); |
| 219 | + if (values == null) { |
| 220 | + if (map != null && map.get(name) != null) { |
| 221 | + setModified(true); |
| 222 | + map.remove(name); |
| 223 | + } |
| 224 | + return; |
| 225 | + } |
| 226 | + if (map == null) { |
| 227 | + map = new LinkedMultiValueMap<>(3); |
| 228 | + setHeader(NATIVE_HEADERS, map); |
| 229 | + } |
| 230 | + if (!ObjectUtils.nullSafeEquals(values, getHeader(name))) { |
| 231 | + setModified(true); |
| 232 | + map.put(name, new ArrayList<>(values)); |
| 233 | + } |
| 234 | + } |
| 235 | + |
204 | 236 | /**
|
205 | 237 | * Add the specified native header value to existing values.
|
206 | 238 | * <p>In order for this to work, the accessor must be {@link #isMutable()
|
|
0 commit comments