-
Notifications
You must be signed in to change notification settings - Fork 38.9k
Description
WebFlux introduced HttpHeaders adapters in Spring Framework 5.1 to map directly to underlying server header API's. Over time a mismatch between MultiValueMap and such header API's became clear.
Typically servers do not store headers in a map, but rather in an ordered collection, e.g. MimeHeaders in Tomcat or HttpFields in Jetty, trading convenience for more efficient access. The loss of efficiency is significant enough, or rather ignoring it can lead to use of innocent looking methods like size() that are inefficient and to real issues like #33823.
In 7.0 HttpHeaders no longer implements MultiValueMap to guide away from Map-like usage, see #33913, adding a dedicated key set to support iterator-based removal, and introducing header-focused alternatives to Map methods.
In 7.0.x we also introduced Servlet API header adapters with #36334, so that both Spring MVC and WebFlux use the header adapter approach.
For 7.1 we can pursue further changes in this direction:
-
decouple adapters from
MutliValueMap, and avoid methods that aren't needed inHttpHeaders:addAll(MultiValueMap<String, String> map) containsValue(Object rawValue) putAll(Map<? extends String, ? extends List<String>> map) values() entrySet()
Use a more focused contract, e.g.
HttpHeadersAdapterand switch existing implementations to it. A default implementation, fornew HttpHeaders(), could useLinkedCaseInsensitiveMapinternally. -
take further advantage of a header-focused contract, e.g. the
putandremovemethods return aListof existing values, which is typically not needed. We could providevoid set(List)and use it everywhere instead. -
The size() method is expensive due to the need to deduplicate across all header fields. We could consider deprecating it in favour of using
headerNames()to obtain a set, which would keep it possible, but not as easy, and more clear. -
HttpHeaders could provide some default implementation of equals/hashcode, useful for testing, so that individual headers adapters don't.