You might have come across a gson exception that says "Expected a string but was BEGIN_OBJECT". This means that you are parsing the response as if it were a string, but actually it is a json object.
I would recommend you to check how to parse json in android if you have no prior knowledge in parsing json
Add these dependencies in your app's build.gradle file
Suppose your response is a json object, something like the following
You will receive the error Expected a string but was BEGIN_OBJECT if you try to parse it like this
GSON will throw the above mentioned error because you have used Call<String> instead of using Call<JsonObject> or using a pojo class
Solution 1 : by using JsonObject:
You can see that here we are expecting a JsonObject as response parameter instead of String. Now we can parse the response correctly as we are expecting the same format mentioned in the response. Also dont forget to change the response param in interface to Call<JsonObject> as shown below
RequestInterface.java
Solution 2 : by using POJO class
First create a pojo class like this
Example.java
Then use it inside your retrofit call like this
RequestInterface.java
I would recommend you to check how to parse json in android if you have no prior knowledge in parsing json
Add these dependencies in your app's build.gradle file
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
Suppose your response is a json object, something like the following
{ "username":"jon", "email":"jon@email.com", "user_array": [ { "user_address":"jon", "user_location":"jon@email.com" }, {..}, . . ] }
You will receive the error Expected a string but was BEGIN_OBJECT if you try to parse it like this
Retrofit retrofit = new Retrofit.Builder() .baseUrl("base_url") .addConverterFactory(GsonConverterFactory.create()) .build(); RequestInterface request = retrofit.create(RequestInterface.class); Call<String> call=request.getJson(); call.enqueue(new Callback<String>() {
@Override public void onResponse(Call<String> call, Response<String> response) { progressDialog.dismiss(); String s= String.valueOf(response.get("username")); JsonArray user_array= response.getAsJsonArray("user_array"); Toast.makeText(PrintTicket.this,response.toString(),Toast.LENGTH_SHORT).show(); } @Override public void onFailure(Call<String> call, Throwable t) { progressDialog.dismiss(); Toast.makeText(PrintTicket.this,t.toString(),Toast.LENGTH_SHORT).show(); } });
GSON will throw the above mentioned error because you have used Call<String> instead of using Call<JsonObject> or using a pojo class
Solution 1 : by using JsonObject:
Retrofit retrofit = new Retrofit.Builder() .baseUrl("base_url") .addConverterFactory(GsonConverterFactory.create()) .build(); RequestInterface request = retrofit.create(RequestInterface.class); Call<JsonObject> call=request.getJson(); call.enqueue(new Callback<JsonObject>() { @Override public void onResponse(Call<JsonObject> call, Response<JsonObject> response) { progressDialog.dismiss(); String s= String.valueOf(response.get("username")); JsonArray user_array= response.getAsJsonArray("user_array"); Toast.makeText(PrintTicket.this,response.toString(),Toast.LENGTH_SHORT).show(); } @Override public void onFailure(Call<JsonObject> call, Throwable t) { progressDialog.dismiss(); Toast.makeText(PrintTicket.this,t.toString(),Toast.LENGTH_SHORT).show(); } });
You can see that here we are expecting a JsonObject as response parameter instead of String. Now we can parse the response correctly as we are expecting the same format mentioned in the response. Also dont forget to change the response param in interface to Call<JsonObject> as shown below
RequestInterface.java
public interface RequestInterface { @GET("api_endpoint") Call<JsonObject> getJson(); }
Solution 2 : by using POJO class
First create a pojo class like this
Example.java
public class Example { @SerializedName("username") @Expose private String username; @SerializedName("email") @Expose private String email; @SerializedName("user_array") @Expose private List<UserArray> userArray = null; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public List<UserArray> getUserArray() { return userArray; } public void setUserArray(List<UserArray> userArray) { this.userArray = userArray; } }
Then use it inside your retrofit call like this
Retrofit retrofit = new Retrofit.Builder() .baseUrl("base_url") .addConverterFactory(GsonConverterFactory.create()) .build(); RequestInterface request = retrofit.create(RequestInterface.class); Call<Example> call=request.getJson(); call.enqueue(new Callback<Example>() { @Override public void onResponse(Call<Example> call, Response<Example> response) { progressDialog.dismiss(); String user_name= response.getUsername(); user_array= new ArrayList<>(response.getUserArray()); Toast.makeText(PrintTicket.this,response.toString(),Toast.LENGTH_SHORT).show(); } @Override public void onFailure(Call<Example> call, Throwable t) { progressDialog.dismiss(); Toast.makeText(PrintTicket.this,t.toString(),Toast.LENGTH_SHORT).show(); } });
RequestInterface.java
public interface RequestInterface { @GET("api_endpoint") Call<Example> getJson(); }
You can use Call<String> as response param only if your response is not enclosed in curly brackets. In this case the response will be a plain text