Skip to content

DefaultServerRequest.ServletParametersMap.entrySet() does not retain HttpServletRequest.getParameterMap() order #36966

Description

@meverden

The org.springframework.web.servlet.function.DefaultServerRequest.ServletParametersMap.entrySet() implementation is terminating the Stream with Collectors.toSet(), which defaults to a HashSet instead of LinkedHashSet. This causes logic that is sensitive to request parameter order to fail.

In the call path below, tomcat-embedded-core and spring-cloud-gateway-server-webmvc try to retain request parameter order, but order is lost due to DefaultServerRequest.ServletParametersMap.entrySet():

org.springframework.cloud.gateway.server.mvc.handler.ProxyExchangeHandlerFunction.handle(ServerRequest)
 |-> org.springframework.cloud.gateway.server.mvc.common.MvcUtils.encodeQueryParams(MultiValueMap<String, String>)
      |-> org.springframework.web.servlet.function.DefaultServerRequest.ServletParametersMap.entrySet()

This prevents spring-cloud-gateway-server-webmvc from being used in front of endpoints that are sensitive to request parameter order, like the Dynatrace OneAgent RUM beacon endpoint, which uses a checksum based on parameter order from the web client's RUM javascript.

Recommend collecting with LinkedHashSet::new.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions