Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Library to convert JSON to urlencoded

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;
}
like image 977
spydon Avatar asked Oct 24 '13 04:10

spydon


3 Answers

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;
}
like image 101
terrakok Avatar answered Oct 22 '22 01:10

terrakok


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

like image 4
hcallejas Avatar answered Oct 22 '22 01:10

hcallejas


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.

like image 4
rasmushaglund Avatar answered Oct 22 '22 00:10

rasmushaglund