Affects: 5.3.27
Some API conventions (particularly JSON:API) use square brackets []
in the naming of HTTP query parameters. Due to historical implementations, a variety of software, specifically including Tomcat, accepts the technically invalid square brackets in query parameter names unencoded, and Spring MVC treats unencoded square brackets as their literal characters, specifically matching them as query parameters for params=
and @RequestParam
.
However, ServletUriComponentsBuilder.fromCurrentRequest()
calls HttpServletRequest#getRequestURI()
and assumes that it is URL-encoded. Subsequently calling build(true)
then results in java.lang.IllegalArgumentException: Invalid character '[' for QUERY_PARAM
.
Calling build(false)
is not a feasible option because the purpose of the fromCurrentRequest()
call is to replace a single parameter using replaceQueryParam
for pagination, and in this case any actually encoded values in the URI from fromCurrentRequest()
will get double-encoded.
Even though permitting square brackets is technically against the spec, Spring MVC should not permit a closed round-trip of ServletUriComponentsBuilder.fromCurrentRequest().build(true)
to throw.
Comment From: rstoyanchev
There is no straight forward way to do that as UriComponents
is unaware of the original URL and is simply validating the individual components that it sees. Although a little less convenient, you can use ServletUriComponentsBuilder.fromCurrentRequest().build(false).toUriString()
which returns all components concatenated without attempting to encode.
Looking at JSON:API spec it seems to expect implementations to encode square brackets: https://jsonapi.org/format/1.1/#appendix-query-details-square-brackets.