Parsing Query Strings on Android

Parsing query strings on Android

Since Android M things have got more complicated. The answer of android.net.URI.getQueryParameter() has a bug which breaks spaces before JellyBean.
Apache URLEncodedUtils.parse() worked, but was deprecated in L, and removed in M.

So the best answer now is UrlQuerySanitizer. This has existed since API level 1 and still exists. It also makes you think about the tricky issues like how do you handle special characters, or repeated values.

The simplest code is

UrlQuerySanitizer.ValueSanitizer sanitizer = UrlQuerySanitizer.getAllButNullLegal();
// remember to decide if you want the first or last parameter with the same name
// If you want the first call setPreferFirstRepeatedParameter(true);
sanitizer.parseUrl(url);
String value = sanitizer.getValue("paramName");

If you are happy with the default parsing behavior you can do:

new UrlQuerySanitizer(url).getValue("paramName")

but you should make sure you understand what the default parsing behavor is, as it might not be what you want.

Escape encoding while parsing query parameter android

Thanks for the responses, I had done it using UrlQuerySanitizer.
Writing the code here.
First, I extended the UrlQuerySanitizer class as

public class CustomUrlQuerySanitizer extends UrlQuerySanitizer {
@Override
protected void parseEntry(String parameter, String value) {
// String unescapedParameter = unescape(parameter);
ValueSanitizer valueSanitizer =
getEffectiveValueSanitizer(parameter);

if (valueSanitizer == null) {
return;
}
// String unescapedValue = unescape(value);
String sanitizedValue = valueSanitizer.sanitize(value);
addSanitizedEntry(parameter, sanitizedValue);
}
}

Then, parsed the url as,

String id = null;
if (uri != null) {
UrlQuerySanitizer urlQuerySanitizer = new CustomUrlQuerySanitizer();

urlQuerySanitizer.registerParameter("id",
new UrlQuerySanitizer.IllegalCharacterValueSanitizer(
UrlQuerySanitizer.IllegalCharacterValueSanitizer.ALL_OK
));
urlQuerySanitizer.parseUrl(uri.toString());
id = urlQuerySanitizer.getValue("id");

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, StandardCharsets.UTF_8),
URLDecoder.decode(value, StandardCharsets.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]}

How can I get parameters from URL in Android?

You can use the Uri class in Android to do this; https://developer.android.com/reference/android/net/Uri.html

Uri uri = Uri.parse("http://www.chalklit.in/post.html?chapter=V-Maths-Addition%20&%20Subtraction&post=394");
String server = uri.getAuthority();
String path = uri.getPath();
String protocol = uri.getScheme();
Set<String> args = uri.getQueryParameterNames();

Then you can even get a specific element from the query parameters as such;

String chapter = uri.getQueryParameter("chapter");  //will return "V-Maths-Addition "

Easiest way to parse individual query parameter data from an API URL on Android Kotlin

Use android.net.UrlQuerySanitizer to parse the individual values from the aforementioned form of API endpoints like this:

import android.net.UrlQuerySanitizer

//..

val sanitizer = UrlQuerySanitizer()
sanitizer.setAllowUnregisteredParamaters(true)
sanitizer.parseUrl(url)
var msg : String? = sanitizer.getValue("msg")

//For removing the "+" signs or any other unwanted signs to get a displayable message like the question:

msg?.let {
if (it.contains("+")) {
msg = it.replace("+", " ")
}
}

Extract parameter values from url android

In Android, you should never use URLEncodedUtils which is now deprecated. A good alternative is to use the Uri class instead: retrieve the query parameter keys using getQueryParameterNames() then iterate on them and retrieve each value using getQueryParameter().

Not able to get query paramter value using android.net.Uri#getQueryParameter

I think that Android's Uri implementation is getting confused over those square brackets, as those appear to be invalid URL syntax.

If you control the Web service, you might reconsider the use of square brackets, as they may cause problems with other clients. Otherwise, you may need to play some icky regex games to replace those square brackets with escaped equivalents or otherwise find ways to sanitize the URL before fully parsing it with Uri.

How to parse query param effectively in java?

Here is another possible solution:

    Pattern pat = Pattern.compile("([^&=]+)=([^&]*)");
Matcher matcher = pat.matcher(requestUri);
Map<String,String> map = new HashMap<>();
while (matcher.find()) {
map.put(matcher.group(1), matcher.group(2));
}
System.out.println(map);

How to do a query in Android using Parse?

Your real problem here is your ArrayAdapter. You would need a custom adapter if you want to use Parse objects as your data type. The built in adapter doesn't know how to use Parse objects and is outputting the object as a string for you. Instead you should do something like

arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, MyNamesList);

Where MyNamesList is of type String.

It's hard to help on your query without more information but you are getting Parse objects back, you just need to get the name out of them with something like

MyList.get(i).getString("name");



Related Topics



Leave a reply



Submit