URL-кодирование с использованием нового Spring UriComponentsBuilder

Я пытаюсь использовать spring UriComponentsBuilder для генерации некоторых URL-адресов для oauth-взаимодействия. Параметры запроса включают такие объекты, как обратные URL-адреса и значения параметров с пробелами в них.

Попытка использования UriComponentBuilder (поскольку UriUtils теперь устарела)

UriComponentsBuilder urlBuilder = UriComponentsBuilder.fromHttpUrl(oauthURL);
urlBuilder.queryParam("client_id", clientId);
urlBuilder.queryParam("redirect_uri", redirectURI);
urlBuilder.queryParam("scope", "test1 test2");

String url = urlBuilder.build(false).encode().toUriString();

К сожалению, в то время как пространство в параметре области области применения успешно заменено на "+", параметр redirect_uri совсем не закодирован url.

Например,

redirect_uri=https://oauth2-login-demo.appspot.com/code

должно было закончиться

redirect_uri=https%3A%2F%2Foauth2-login-demo.appspot.com%2Fcode

но не затронута. Дайвинг в код, в частности org.springframework.web.util.HierarchicalUriComponents.Type.QUERY_PARAM.isAllowed(c):

if ('=' == c || '+' == c || '&' == c) {
  return false;
}
else {
  return isPchar(c) || '/' == c || '?' == c;
}

четко разрешает символы ':' и '/', которые по десне его не должны. Он должен делать какой-то другой тип кодирования, хотя для жизни меня я не могу представить, что. Я здесь лаяю неправильное дерево здесь?

Спасибо

Ответы

Ответ 1

UriComponentsBuilder кодирует ваш URI в соответствии с RFC 3986, при этом раздел 3.4 о компоненте "запрос" URI заслуживает особого внимания.

В компоненте 'query' символы '/' и ':' разрешены и не нуждаются в экранировании.

Например, символ "/": компонент "запрос" (который четко ограничен неэкранированными символами "?" И (необязательно) "#") не является иерархическим, и символ "/" не имеет специального значения. Так что это не нуждается в кодировании.

Ответ 2

из того, что я понимаю, UriComponentsBuilder автоматически не кодирует параметры запроса, а только экземпляр HttpUrl, созданный им. Другими словами, вы все равно должны явно кодировать:

String redirectURI= "https://oauth2-login-demo.appspot.com/code";
urlBuilder.queryParam("redirect_uri", URLEncoder.encode(redirectURI,"UTF-8" ));

Ответ 3

Попробуйте отсканировать документ UriComponentsBuilder, есть метод с именем build (в булевском кодировании)

Пример кода 1:

UriComponents uriComponents = UriComponentsBuilder.fromPath("/path1/path2").build(true);

Вот мой пример кода 2:

UriComponents uriComponents = UriComponentsBuilder.newInstance()
            .scheme("https")
            .host("my.host")
            .path("/path1/path2").query(parameters).build(true);

URI uri= uriComponents.toUri();

ResponseEntity<MyEntityResponse> responseEntity = restTemplate.exchange(uri,
            HttpMethod.GET, entity, typeRef);