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);