我得到了这样的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方法。


当前回答

有一个新版本的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)));
}

其他回答

如果你正在使用Spring框架:

public static void main(String[] args) {
    String uri = "http://my.test.com/test?param1=ab&param2=cd&param2=ef";
    MultiValueMap<String, String> parameters =
            UriComponentsBuilder.fromUriString(uri).build().getQueryParams();
    List<String> param1 = parameters.get("param1");
    List<String> param2 = parameters.get("param2");
    System.out.println("param1: " + param1.get(0));
    System.out.println("param2: " + param2.get(0) + "," + param2.get(1));
}

你会得到:

param1: ab
param2: cd,ef

org.keycloak.common.util.UriUtils

我不得不在Keycloak扩展中解析uri和查询参数,并发现这个实用工具类非常有用:

org.keycloak.common.util.UriUtils:
static MultivaluedHashMap<String,String> decodeQueryString(String queryString) 

还有一个有用的方法可以删除一个查询参数:

static String   stripQueryParam(String url, String name)

解析URL有 org.keycloak.common.util.KeycloakUriBuilder:

KeycloakUriBuilder  uri(String uriTemplate)
String  getQuery()

还有很多其他的好东西。

一个kotlin版本

由马提亚提供的答案

fun decomposeQueryString(query: String, charset: Charset): Map<String, String?> {
   return if (query.split("?").size <= 1)
       emptyMap()
   else {
       query.split("?")[1]
            .split("&")
            .map { it.split(Pattern.compile("="), 2) }
            .associate {
                Pair(
                        URLDecoder.decode(it[0], charset.name()),
                        if (it.size > 1) URLDecoder.decode(it[1], charset.name()) else null
                )
            }
     }
}

这需要问号'?’。

Hutool框架通过HttpUtil来支持这一点。例子:

import cn.hutool.http.HttpUtil;

    String url ="https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback";
    Map<String, List<String>> stringListMap = HttpUtil.decodeParams(url, "UTF-8");
    System.out.println("decodeParams:" + stringListMap);

你会得到:

decodeParams:{client_id=[SS], response_type=[code], scope=[N_FULL], access_type=[offline], redirect_uri=[http://localhost/Callback]}

只是Java 8版本的更新

public Map<String, List<String>> splitQuery(URL url) {
    if (Strings.isNullOrEmpty(url.getQuery())) {
        return Collections.emptyMap();
    }
    return Arrays.stream(url.getQuery().split("&"))
            .map(this::splitQueryParameter)
            .collect(Collectors.groupingBy(SimpleImmutableEntry::getKey, LinkedHashMap::new, **Collectors**.mapping(Map.Entry::getValue, **Collectors**.toList())));
}

mapping和toList()方法必须用于顶部答案中没有提到的collector。否则它会在IDE中抛出编译错误