Steven Schoen
Steven Schoen

Reputation: 4386

GSON: Expected a string but was BEGIN_OBJECT?

I'm trying to use GSON to parse some very simple JSON. Here's my code:

    Gson gson = new Gson();

    InputStreamReader reader = new InputStreamReader(getJsonData(url));
    String key = gson.fromJson(reader, String.class);

Here's the JSON returned from the url:

{
  "access_token": "abcdefgh"
}

I'm getting this exception:

E/AndroidRuntime(19447): com.google.gson.JsonSyntaxException:     java.lang.IllegalStateException: Expected a string but was BEGIN_OBJECT at line 1 column 2

Any ideas? I'm new to GSON.

Upvotes: 20

Views: 48523

Answers (3)

mani
mani

Reputation: 799

This is normal parsing exception occurred when Pojo key data type is different from json response

This is due to data type mismatch in Pojo class and actually data which comes in the Network api Response

Eg

data class ProcessResponse(
        val outputParameters: String,
        val pId: Int 
    )

got the same error due to api gives response as

 {
        "pId": 1",
        "outputParameters": {
          "": ""
        }
    }

Here POJO is outputParameters is String but as per api response its json

Upvotes: 1

giampaolo
giampaolo

Reputation: 6934

Another "low level" possibility using the Gson JsonParser:

package stackoverflow.questions.q11571412;

import com.google.gson.*;

public class GsonFooWithParser
{
  public static void main(String[] args)
  {
    String jsonInput = "{\"access_token\": \"abcdefgh\"}";

    JsonElement je = new JsonParser().parse(jsonInput);

    String value = je.getAsJsonObject().get("access_token").getAsString();
    System.out.println(value);
  }
}

If one day you'll write a custom deserializer, JsonElement will be your best friend.

Upvotes: 5

Programmer Bruce
Programmer Bruce

Reputation: 66943

The JSON structure is an object with one element named "access_token" -- it's not just a simple string. It could be deserialized to a matching Java data structure, such as a Map, as follows.

import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class GsonFoo
{
  public static void main(String[] args)
  {
    String jsonInput = "{\"access_token\": \"abcdefgh\"}";

    Map<String, String> map = new Gson().fromJson(jsonInput, new TypeToken<Map<String, String>>() {}.getType());
    String key = map.get("access_token");
    System.out.println(key);
  }
}

Another common approach is to use a more specific Java data structure that matches the JSON. For example:

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;

public class GsonFoo
{
  public static void main(String[] args)
  {
    String jsonInput = "{\"access_token\": \"abcdefgh\"}";

    Response response = new Gson().fromJson(jsonInput, Response.class);
    System.out.println(response.key);
  }
}

class Response
{
  @SerializedName("access_token")
  String key;
}

Upvotes: 27

Related Questions