我得到了这样的URI:
https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback
我需要一个包含已解析元素的集合:
NAME VALUE
------------------------
client_id SS
response_type code
scope N_FULL
access_type offline
redirect_uri http://localhost/Callback
确切地说,我需要一个与c# /等价的Java。净HttpUtility。ParseQueryString方法。
如果只是想从字符串URL后的参数。然后下面的代码将工作。我只是假设简单的Url。我的意思是没有严格和快速的检查和解码。就像在我的一个测试案例中,我得到了Url,我知道我只需要参数的值。url很简单。不需要编码解码。
String location = "https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback";
String location1 = "https://stackoverflow.com?param1=value1¶m2=value2¶m3=value3";
String location2 = "https://stackoverflow.com?param1=value1¶m2=¶m3=value3¶m3";
Map<String, String> paramsMap = Stream.of(location)
.filter(l -> l.indexOf("?") != -1)
.map(l -> l.substring(l.indexOf("?") + 1, l.length()))
.flatMap(q -> Pattern.compile("&").splitAsStream(q))
.map(s -> s.split("="))
.filter(a -> a.length == 2)
.collect(Collectors.toMap(
a -> a[0],
a -> a[1],
(existing, replacement) -> existing + ", " + replacement,
LinkedHashMap::new
));
System.out.println(paramsMap);
谢谢
有一个新版本的Apache HTTP客户端- org.apache.httpcomponents。client5 -其中URLEncodedUtils现在已弃用。应该改为使用URIBuilder:
import org.apache.hc.core5.http.NameValuePair;
import org.apache.hc.core5.net.URIBuilder;
private static Map<String, String> getQueryParameters(final String url) throws URISyntaxException {
return new URIBuilder(new URI(url), StandardCharsets.UTF_8).getQueryParams()
.stream()
.collect(Collectors.toMap(NameValuePair::getName,
nameValuePair -> URLDecoder.decode(nameValuePair.getValue(), StandardCharsets.UTF_8)));
}
纯Java 11
给定要分析的URL:
URL url = new URL("https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback");
这个解决方案收集了一个对列表:
List<Map.Entry<String, String>> list = Pattern.compile("&")
.splitAsStream(url.getQuery())
.map(s -> Arrays.copyOf(s.split("=", 2), 2))
.map(o -> Map.entry(decode(o[0]), decode(o[1])))
.collect(Collectors.toList());
另一方面,这个解决方案收集一个映射(假设在url中可以有更多具有相同名称但不同值的参数)。
Map<String, List<String>> list = Pattern.compile("&")
.splitAsStream(url.getQuery())
.map(s -> Arrays.copyOf(s.split("=", 2), 2))
.collect(groupingBy(s -> decode(s[0]), mapping(s -> decode(s[1]), toList())));
这两种解决方案都必须使用实用函数来正确解码参数。
private static String decode(final String encoded) {
return Optional.ofNullable(encoded)
.map(e -> URLDecoder.decode(e, StandardCharsets.UTF_8))
.orElse(null);
}