Skip to content

Commit 9729b46

Browse files
committed
Retain entry set order in read-only HttpHeaders
Prior to this commit, the entry set of read-only HttpHeaders lost the original headers' ordering. The changes in commit ce7278a introduced a regression in the read-only HttpHeaders support. Specifically, the implementation of entrySet() in the internal ReadOnlyHttpHeaders class converted the original entry set to an immutable, non-ordered set of immutable entries. This commit fixes this issue by converting the original entry set to an immutable, ordered set of immutable entries. Closes gh-23551
1 parent a496353 commit 9729b46

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

spring-web/src/main/java/org/springframework/http/ReadOnlyHttpHeaders.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@
1616

1717
package org.springframework.http;
1818

19-
import java.util.AbstractMap;
19+
import java.util.AbstractMap.SimpleImmutableEntry;
2020
import java.util.Collection;
2121
import java.util.Collections;
22+
import java.util.LinkedHashSet;
2223
import java.util.List;
2324
import java.util.Map;
2425
import java.util.Set;
@@ -31,6 +32,7 @@
3132
* {@code HttpHeaders} object that can only be read, not written to.
3233
*
3334
* @author Brian Clozel
35+
* @author Sam Brannen
3436
* @since 5.1.1
3537
*/
3638
class ReadOnlyHttpHeaders extends HttpHeaders {
@@ -141,9 +143,10 @@ public Collection<List<String>> values() {
141143

142144
@Override
143145
public Set<Entry<String, List<String>>> entrySet() {
144-
return Collections.unmodifiableSet(this.headers.entrySet().stream()
145-
.map(AbstractMap.SimpleImmutableEntry::new)
146-
.collect(Collectors.toSet()));
146+
return this.headers.entrySet().stream().map(SimpleImmutableEntry::new)
147+
.collect(Collectors.collectingAndThen(
148+
Collectors.toCollection(LinkedHashSet::new), // Retain original ordering of entries
149+
Collections::unmodifiableSet));
147150
}
148151

149152
}

spring-web/src/test/java/org/springframework/http/HttpHeadersTests.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.GregorianCalendar;
3333
import java.util.List;
3434
import java.util.Locale;
35+
import java.util.Map.Entry;
3536
import java.util.TimeZone;
3637

3738
import org.hamcrest.Matchers;
@@ -47,6 +48,7 @@
4748
* @author Sebastien Deleuze
4849
* @author Brian Clozel
4950
* @author Juergen Hoeller
51+
* @author Sam Brannen
5052
*/
5153
public class HttpHeadersTests {
5254

@@ -557,4 +559,20 @@ public void bearerAuth() {
557559
assertEquals("Bearer foo", authorization);
558560
}
559561

562+
@Test
563+
public void readOnlyHttpHeadersRetainEntrySetOrder() {
564+
headers.add("aardvark", "enigma");
565+
headers.add("beaver", "enigma");
566+
headers.add("cat", "enigma");
567+
headers.add("dog", "enigma");
568+
headers.add("elephant", "enigma");
569+
570+
String[] expectedKeys = new String[] { "aardvark", "beaver", "cat", "dog", "elephant" };
571+
572+
assertArrayEquals(expectedKeys, headers.entrySet().stream().map(Entry::getKey).toArray());
573+
574+
HttpHeaders readOnlyHttpHeaders = HttpHeaders.readOnlyHttpHeaders(headers);
575+
assertArrayEquals(expectedKeys, readOnlyHttpHeaders.entrySet().stream().map(Entry::getKey).toArray());
576+
}
577+
560578
}

0 commit comments

Comments
 (0)