Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse a URI String into Name-Value Collection

I've got the URI like this:

https://google.com.ua/oauth/authorize?client_id=SS&response_type=code&scope=N_FULL&access_type=offline&redirect_uri=http://localhost/Callback 

I need a collection with parsed elements:

NAME               VALUE ------------------------ client_id          SS response_type      code scope              N_FULL access_type        offline redirect_uri       http://localhost/Callback 

To be exact, I need a Java equivalent for the C#/.NET HttpUtility.ParseQueryString method.

like image 656
Sergey Shafiev Avatar asked Nov 27 '12 20:11

Sergey Shafiev


People also ask

How do you separate a query string from a URL?

The query string is composed of a series of field-value pairs. Within each pair, the field name and value are separated by an equals sign, " = ". The series of pairs is separated by the ampersand, " & " (or semicolon, " ; " for URLs embedded in HTML and not generated by a <form>...

What is request QueryString?

The value of Request. QueryString(parameter) is an array of all of the values of parameter that occur in QUERY_STRING. You can determine the number of values of a parameter by calling Request. QueryString(parameter).

What is a URI query?

URI parameter (Path Param) is basically used to identify a specific resource or resources whereas Query Parameter is used to sort/filter those resources. Let's consider an example where you want identify the employee on the basis of employeeID, and in that case, you will be using the URI param.


2 Answers

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]} 
like image 155
Pr0gr4mm3r Avatar answered Sep 18 '22 04:09

Pr0gr4mm3r


org.apache.http.client.utils.URLEncodedUtils

is a well known library that can do it for you

import org.apache.hc.client5.http.utils.URLEncodedUtils  String 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 : 1 two : 2 three : 3 three : 3a 
like image 20
Juan Mendes Avatar answered Sep 22 '22 04:09

Juan Mendes