使用新的Spring UriComponentsBuilder进行URL编码

时间:2013-08-08 23:38:32

标签: spring

我正在尝试使用spring的UriComponentsBuilder来生成一些用于oauth交互的URL。查询参数包括诸如回调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();

不幸的是,虽然scope参数中的空格已成功替换为'+',但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;
}

显然允许使用':'和'/'字符,这不应该是口香糖。它必须做一些其他类型的编码,虽然对于我的生活,我无法想象什么。我在这里吠叫了错误的树吗?

由于

3 个答案:

答案 0 :(得分:20)

UriComponentsBuilder根据RFC 3986对您的URI进行编码,第3.4节中有关URI的'query'组件特别注意。

在'query'组件中,​​允许使用字符'/'和':',并且不需要转义。

以'/'字符为例:'query'组件(由未转义的'?'和(可选)'#'字符明确分隔),不是分层的,'/'字符没有特殊含义。所以它不需要编码。

答案 1 :(得分:13)

根据我的理解,UriComponentsBuilder不会自动编码查询参数,只是它实例化的原始HttpUrl。换句话说,您仍然必须明确编码:

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

答案 2 :(得分:1)

尝试扫描UriComponentsBuilder文档,有一个名为build(boolean encoded)的方法

示例代码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);