We are doing some integration towards a quite inconsistent (Zurmo-)REST API. The API only accepts urlencoded strings as its payload in the http posts, but it answers with JSON. So as the documentation was very unclear on this we naturally thought we could post JSON to it, but this was not the case.
So now we have all our code generating JSON when we need to send it as x-www-form-urlencoded, is there any java library that can do a conversion from JSON to an urlencoded string?
We are currently using the org.json lib, but we can change it if there would be a need for it.
Example:
This JSON string:
{"data":{"description":"test","occurredOnDateTime":"2013-10-24 01:44:50"}}
Should be converted into this:
data%5Bdescription%5D=test&data%5BoccurredOnDateTime%5D=2013-10-24+01%3A44%3A50
Java code:
We translated rasmushaglunds javascript code to java and wrapped it, here is the result if anybody else stumbles upon this problem.
public static String jsonToURLEncoding(JSONObject json) {
String output = "";
String[] keys = JSONObject.getNames(json);
for (String currKey : keys)
output += jsonToURLEncodingAux(json.get(currKey), currKey);
return output.substring(0, output.length()-1);
}
private static String jsonToURLEncodingAux(Object json, String prefix) {
String output = "";
if (json instanceof JSONObject) {
JSONObject obj = (JSONObject)json;
String[] keys = JSONObject.getNames(obj);
for (String currKey : keys) {
String subPrefix = prefix + "[" + currKey + "]";
output += jsonToURLEncodingAux(obj.get(currKey), subPrefix);
}
} else if (json instanceof JSONArray) {
JSONArray jsonArr = (JSONArray) json;
int arrLen = jsonArr.length();
for (int i = 0; i < arrLen; i++) {
String subPrefix = prefix + "[" + i + "]";
Object child = jsonArr.get(i);
output += jsonToURLEncodingAux(child, subPrefix);
}
} else {
output = prefix + "=" + json.toString() + "&";
}
return output;
}
public static String objectToUrlEncodedString(Object object, Gson gson) {
return jsonToUrlEncodedString((JsonObject) new JsonParser().parse(gson.toJson(object)));
}
private static String jsonToUrlEncodedString(JsonObject jsonObject) {
return jsonToUrlEncodedString(jsonObject, "");
}
private static String jsonToUrlEncodedString(JsonObject jsonObject, String prefix) {
String urlString = "";
for (Map.Entry<String, JsonElement> item : jsonObject.entrySet()) {
if (item.getValue() != null && item.getValue().isJsonObject()) {
urlString += jsonToUrlEncodedString(
item.getValue().getAsJsonObject(),
prefix.isEmpty() ? item.getKey() : prefix + "[" + item.getKey() + "]"
);
} else {
urlString += prefix.isEmpty() ?
item.getKey() + "=" + item.getValue().getAsString() + "&" :
prefix + "[" + item.getKey() + "]=" + item.getValue().getAsString() + "&";
}
}
return urlString;
}
There is an easier way now, and that is to use the URLEncoder.encode
method.
Import the URLEncoder
package:
import java.net.URLEncoder;
and then:
URLEncoder.encode(objectMapper.writeValueAsString(<yourClass>), StandardCharsets.UTF_8.toString());
You can test your result here:
https://onlinejsontools.com/url-decode-json
As noted below, it's not a Java library but you should be able to translate it :)
Here's how you could do it in javascript:
var jsonArrayToUrl = function (obj, prefix) {
var urlString = "";
for (var key in obj) {
if (obj[key] !== null && typeof obj[key] == "object") {
prefix += "[" + key + "]";
urlString += jsonArrayToUrl(obj[key], prefix);
}else{
urlString += prefix + "[" + key + "]=" + obj[key] + "&";
}
}
return encodeURIComponent(urlString);
};
Then call it with
jsonArrayToUrl(test["data"], "data");
By the example string you gave above it returns
"data%5Bdescription%5D%3Dtest%26data%5BoccurredOnDateTime%5D%3D2013-10-24%2001%3A44%3A50%26"
It should work recursively on nested arrays. You might also consider writing a wrapper for the function so that you only need one argument.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With