Parse a URI String into Name-Value Collection Parse a URI String into Name-Value Collection java java

Parse a URI String into Name-Value Collection


If you are looking for a way to achieve it without using an external library, the following code will help you.

public static Map<String, String> splitQuery(URL url) throws UnsupportedEncodingException {    Map<String, String> query_pairs = new LinkedHashMap<String, String>();    String query = url.getQuery();    String[] pairs = query.split("&");    for (String pair : pairs) {        int idx = pair.indexOf("=");        query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));    }    return query_pairs;}

You can access the returned Map using <map>.get("client_id"), with the URL given in your question this would return "SS".

UPDATE URL-Decoding added

UPDATE As this answer is still quite popular, I made an improved version of the method above, which handles multiple parameters with the same key and parameters with no value as well.

public static Map<String, List<String>> splitQuery(URL url) throws UnsupportedEncodingException {  final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();  final String[] pairs = url.getQuery().split("&");  for (String pair : pairs) {    final int idx = pair.indexOf("=");    final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;    if (!query_pairs.containsKey(key)) {      query_pairs.put(key, new LinkedList<String>());    }    final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;    query_pairs.get(key).add(value);  }  return query_pairs;}

UPDATE Java8 version

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, mapping(Map.Entry::getValue, toList())));}public SimpleImmutableEntry<String, String> splitQueryParameter(String it) {    final int idx = it.indexOf("=");    final String key = idx > 0 ? it.substring(0, idx) : it;    final String value = idx > 0 && it.length() > idx + 1 ? it.substring(idx + 1) : null;    return new SimpleImmutableEntry<>(        URLDecoder.decode(key, "UTF-8"),        URLDecoder.decode(value, "UTF-8")    );}

Running the above method with the URL

https://stackoverflow.com?param1=value1&param2=&param3=value3&param3

returns this Map:

{param1=["value1"], param2=[null], param3=["value3", null]}


org.apache.http.client.utils.URLEncodedUtils

is a well known library that can do it for you

import org.apache.hc.client5.http.utils.URLEncodedUtilsString url = "http://www.example.com/something.html?one=1&two=2&three=3&three=3a";List<NameValuePair> params = URLEncodedUtils.parse(new URI(url), Charset.forName("UTF-8"));for (NameValuePair param : params) {  System.out.println(param.getName() + " : " + param.getValue());}

Outputs

one : 1two : 2three : 3three : 3a


If you are using Spring Framework:

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

You will get:

param1: abparam2: cd,ef