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¶m2=¶m3=value3¶m3
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¶m2=cd¶m2=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