1111import java .lang .invoke .MethodHandle ;
1212import java .lang .invoke .MethodHandles ;
1313import java .lang .invoke .MethodType ;
14- import java .util .HashSet ;
1514import java .util .List ;
1615import java .util .Map ;
1716import java .util .Set ;
18- import java .util .function .BiConsumer ;
1917import java .util .function .Supplier ;
2018import javax .annotation .Nullable ;
2119import org .springframework .http .HttpHeaders ;
2826public final class HeaderUtil {
2927
3028 @ Nullable private static final MethodHandle GET_HEADERS ;
31- @ Nullable private static final MethodHandle FOR_EACH ;
32- @ Nullable private static final MethodHandle KEY_SET ;
29+ @ Nullable private static final MethodHandle HEADER_NAMES ;
3330
3431 static {
3532 GET_HEADERS =
@@ -41,31 +38,15 @@ public final class HeaderUtil {
4138 MethodType .methodType (List .class , Object .class ))); // before spring web 7.0
4239
4340 // Spring Web 7+
44- MethodHandle forEach = null ;
41+ MethodHandle headerNames = null ;
4542 try {
46- forEach =
43+ headerNames =
4744 MethodHandles .lookup ()
48- .findVirtual (
49- HttpHeaders .class ,
50- "forEach" ,
51- MethodType .methodType (void .class , BiConsumer .class ));
45+ .findVirtual (HttpHeaders .class , "headerNames" , MethodType .methodType (Set .class ));
5246 } catch (Throwable t ) {
53- // ignore - will fall back to keySet
47+ // ignore - will fall back to casting to Map
5448 }
55- FOR_EACH = forEach ;
56-
57- // Spring Web 6 and earlier
58- MethodHandle keySet = null ;
59- if (FOR_EACH == null ) {
60- try {
61- keySet =
62- MethodHandles .lookup ()
63- .findVirtual (Map .class , "keySet" , MethodType .methodType (Set .class ));
64- } catch (Throwable t ) {
65- // ignore
66- }
67- }
68- KEY_SET = keySet ;
49+ HEADER_NAMES = headerNames ;
6950 }
7051
7152 @ Nullable
@@ -100,22 +81,19 @@ public static List<String> getHeader(HttpHeaders headers, String name) {
10081
10182 @ SuppressWarnings ("unchecked" ) // HttpHeaders is a Map in Spring Web 6 and earlier
10283 public static Set <String > getKeys (HttpHeaders headers ) {
103- if (FOR_EACH != null ) {
104- // Spring Web 7: HttpHeaders has forEach(BiConsumer ) method
84+ if (HEADER_NAMES != null ) {
85+ // Spring Web 7: HttpHeaders has headerNames( ) method
10586 try {
106- Set <String > keys = new HashSet <>();
107- FOR_EACH .invoke (headers , (BiConsumer <String , ?>) (key , value ) -> keys .add (key ));
108- return keys ;
87+ Set <String > result = (Set <String >) HEADER_NAMES .invoke (headers );
88+ if (result != null ) {
89+ return result ;
90+ }
10991 } catch (Throwable t ) {
11092 // ignore
11193 }
112- } else if ( KEY_SET != null ) {
94+ } else {
11395 // Spring Web 6 and earlier: HttpHeaders extends Map
114- try {
115- return (Set <String >) KEY_SET .invoke (headers );
116- } catch (Throwable t ) {
117- // ignore
118- }
96+ return ((Map <String , List <String >>) headers ).keySet ();
11997 }
12098 return emptySet ();
12199 }
0 commit comments