使用新的 Spring UriComponentsBuilder 进行 URL 编码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18138011/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
URL encoding using the new Spring UriComponentsBuilder
提问by ticktock
I'm attempting to use spring's UriComponentsBuilder to generate some urls for oauth interaction. The query parameters include such entities as callback urls and parameter values with spaces in them.
我正在尝试使用 spring 的 UriComponentsBuilder 为 oauth 交互生成一些 url。查询参数包括回调 url 和带有空格的参数值等实体。
Attempting to use UriComponentBuilder (because UriUtils is now deprecated)
尝试使用 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();
Unfortunately, while the space in the scope parameter is successfully replaced with '+', the redirect_uri parameter is not at all url encoded.
不幸的是,虽然 scope 参数中的空格已成功替换为“+”,但 redirect_uri 参数根本没有进行 url 编码。
E.g,
例如,
redirect_uri=https://oauth2-login-demo.appspot.com/code
should have ended up
应该结束
redirect_uri=https%3A%2F%2Foauth2-login-demo.appspot.com%2Fcode
but was untouched. Diving into the code, specifically org.springframework.web.util.HierarchicalUriComponents.Type.QUERY_PARAM.isAllowed(c) :
但未受影响。深入研究代码,特别是 org.springframework.web.util.HierarchicalUriComponents.Type.QUERY_PARAM.isAllowed(c) :
if ('=' == c || '+' == c || '&' == c) {
return false;
}
else {
return isPchar(c) || '/' == c || '?' == c;
}
clearly allows ':' and '/' characters, which by gum, it shouldn't. It must be doing some other type of encoding, though for the life of me, I can't imagine what. Am I barking up the wrong tree(s) here?
明确允许使用 ':' 和 '/' 字符,这不应该。它一定是在做一些其他类型的编码,但对于我的生活,我无法想象是什么。我在这里吠错树了吗?
Thanks
谢谢
采纳答案by simonh
UriComponentsBuilderis encoding your URI in accordance with RFC 3986, with section 3.4 about the 'query' component of a URI being of particular note.
UriComponentsBuilder正在根据RFC 3986对您的 URI 进行编码,特别注意第 3.4 节关于 URI 的“查询”组件。
Within the 'query' component, the characters '/' and ':' are permitted, and do not need escaping.
在 'query' 组件中,字符 '/' 和 ':' 是允许的,不需要转义。
To take the '/' character for example: the 'query' component (which is clearly delimited by unescaped '?' and (optionally) '#' characters), is not hierarchical and the '/' character has no special meaning. So it doesn't need encoding.
以 '/' 字符为例:'query' 组件(由未转义的 '?' 和(可选)'#' 字符明确分隔)不是分层的,并且 '/' 字符没有特殊含义。所以它不需要编码。
回答by Black
from what I understand, UriComponentsBuilder doesn't encode the query parameters automatically, just the original HttpUrl it's instantiated with. In other words, you still have to explicitly encode:
据我了解, UriComponentsBuilder 不会自动对查询参数进行编码,只会对它实例化的原始 HttpUrl 进行编码。换句话说,您仍然必须显式编码:
String redirectURI= "https://oauth2-login-demo.appspot.com/code";
urlBuilder.queryParam("redirect_uri", URLEncoder.encode(redirectURI,"UTF-8" ));
回答by Andrew
Try to scan the UriComponentsBuilder doc, there is method named build(boolean encoded)
尝试扫描 UriComponentsBuilder 文档,有一个名为 build(boolean encoding) 的方法
Sample code 1:
示例代码 1:
UriComponents uriComponents = UriComponentsBuilder.fromPath("/path1/path2").build(true);
Here is my sample code 2:
这是我的示例代码 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);

