42

Running a Play! app with Scala. I'm doing a request where the response is expected to be a JSON string. When checking the debugger, the JsonElement returns OK with all information as expected. However, the problem is when I try to actually run methods on that JsonElement.

val json = WS.url("http://maps.googleapis.com/maps/api/geocode/json?callback=?&sensor=true&address=%s", startAddress+","+startCity+","+startProvince).get.getJson
    val geocoder = json.getAsString

The only error I get back is Unsupported Operation Exception: null and I've tried this on getAsString and getAsJsonObject and getAsJsonPrimitive

Any idea why it's failing on all methods? Thanks.

crockpotveggies
  • 11,654
  • 11
  • 65
  • 127

4 Answers4

55

I had a similar problem and I had to change jsonObject.getAsString() to jsonObject.toString();

Iman Marashi
  • 4,677
  • 33
  • 48
lleclerc
  • 623
  • 5
  • 10
  • 2
    Looking at the github repo, it seems the getAsString() method is not implemented yet. It just throws unsupported exception no matter what. https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/JsonElement.java – Lev Stefanovich Feb 24 '17 at 19:31
  • 1
    I believe this is because the getAsString() function is expected to return a sub-property of the root element as a string, not the root element itself. If you have a json such as {"foo":{"bar":"foobar"}} then calling json.get("foo").getAsString() would return the string {"bar":"foobar"}. – Aaron St. Clair Aug 10 '17 at 16:50
55

Maybe your JsonElement is a JsonNull

What you could do is to first check that it isn't by using json.isJsonNull

Otherwise, try to get its String representation with json.toString

Vishrant
  • 10,695
  • 8
  • 48
  • 87
Andy Petrella
  • 4,325
  • 24
  • 29
11

In my case I just needed to get the element as an empty string if it is null, so I wrote a function like this:

private String getNullAsEmptyString(JsonElement jsonElement) {
        return jsonElement.isJsonNull() ? "" : jsonElement.getAsString();
    }

So instead of

val geocoder = json.getAsString

You can just use this

val geocoder = getNullAsEmptyString(json);

It returns "" if the element is null and the actual string if it is not

Henry
  • 901
  • 11
  • 14
-1

The class JsonElement will throw Unsupported Operation Exception for any getAs<Type> method, because it's an abstract class and makes sense that it is implemented in this way.

For some reason the class JsonObject, does not implement the getAs<Type> methods, so any call to one of these methods will throw an exception.

Calling the toString method on a JsonElement object, may solve your issue in certain circumstances, but isn't probably what you want because it returns the json representation as String (e.g. \"value\") in some cases.

I found out that also a JsonPrimitive class exists and it does implement the getAs<Type> methods. So probably the correct way to proceed is something like this:

    String input = "{\"key1\":\"value1\",\"key2\":\"value2\"}";
    JsonParser parser = new JsonParser();
    JsonElement jsonTree = parser.parse(input);

    if(jsonTree != null && jsonTree.isJsonObject()) {
        JsonObject jsonObject = jsonTree.getAsJsonObject();
        value = jsonObject.get("key1").getAsJsonPrimitive().getAsString()
    }

PS. I removed all the nullability mgmt part. If you are coding in Java you probably want to manage this in a better way.

see GitHub source code for JsonElement: https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/JsonElement.java#L178

Hammond95
  • 540
  • 5
  • 16