Кодирование параметров запроса с помощью UriComponentsBuilder
Я изо всех сил пытаюсь понять поведение UriComponentsBuilder
, Я хочу использовать его для кодирования URL-адреса в параметре запроса, однако он, по-видимому, только экранирует %
символы, но не другие необходимые символы, такие как &
,
Пример URL в параметре запроса, который вообще не кодируется:
UriComponentsBuilder.fromUri("http://example.com/endpoint")
.queryParam("query", "/path?foo=foo&bar=bar")
.build();
Выход: http://example.com/endpoint?query=/path?foo=foo&bar=bar
Это не правильно, потому что незашифрованный &
причины bar=bar
интерпретироваться как параметр запроса /endpoint
вместо /path
,
Однако, если я использую вход, который содержит %
персонаж::
UriComponentsBuilder.fromUri("http://example.com/endpoint")
.queryParam("query", "/path?foo=%20bar")
.build();
Выход: http://example.com/endpoint?query=/path?foo=%2520bar
%
персонаж сбежал.
Кажется непоследовательным, что UriComponentsBuilder
будет автоматически избегать %
символы, но не другие зарезервированные символы.
Какой правильный процесс для кодирования URL в параметр запроса с UriComponentsBuilder
?
2 ответа
В вашем примере сборка UriComponents
объект не закодирован или не нормализован. Чтобы убедиться, что применяется кодировка:
Кодируй это сам, позвонив
encode()
метод (см. такжеnormalize()
метод):UriComponents u = UriComponentsBuilder.fromHttpUrl("http://example.com/endpoint") .queryParam("query", "/path?foo=foo&bar=bar") .build() .encode(); // http://example.com/endpoint?query=/path?foo%3Dfoo%26bar%3Dbar
использование
build(true)
метод, если параметры, используемые для построенияUriComponents
уже закодированыUriComponents u = UriComponentsBuilder.fromHttpUrl("http://example.com/endpoint") .queryParam("query", "/path?foo=foo&bar=bar") .build(true); // IllegalArgumentException: Invalid character '=' for QUERY_PARAM in "/path?foo=foo&bar=bar"
Под капотом HierarchicalUriComponents.encode(String)
Метод выполняет фактическое кодирование. После нескольких внутренних звонков он вызывает HierarchicalUriComponents.encodeBytes(byte[], HierarchicalUriComponents.Type)
где HierarchicalUriComponents.Type
enum контролирует, какие символы разрешены в какой части URL. Эта проверка основана на RFC 3986. Короче говоря, у Spring есть своя логика кодирования для каждой части URL.
Неверный синтаксис при использовании
UriComponentsBuilder.fromUri()
сString
параметр вместоURI
, Если вы хотите передать URL какString
используйте это как:UriComponentsBuilder .fromUriString("http://example.com/endpoint") .queryParam("query", URLEncoder.encode("/path?foo=%20bar","UTF-8")) .build();
&
является допустимым символом URL, поэтому он не будет закодирован, но%
не поэтому он декодируется%25
,
Если вы хотите увидеть, как использовать то же самое с RestTemplate
см.: RestTemplate.exchange () не кодирует "+"?