tommus tommus - 2 years ago 97
Java Question

How to parse list of JSON objects surrounded by [] using Retrofit an GSON?

I've created a simple REST endpoint:


This URL returns a very simple response containing a json array as follows:

{ "id":1, "name":"Small", "active":true },
{ "id":2, "name":"Medium", "active":true },
{ "id":3, "name":"Large", "active":true }

Now, I'm trying to consume this response using Retrofit 2 with GSON.

I've added a model:

public class Size {
private int id;
private String name;
private boolean active;

private String createdAt;

private String updatedAt;

And service:

public interface Service {
Call<List<Size>> loadSizes();

I've instantiated a Retrofit:

Retrofit retrofit = new Retrofit.Builder()

And my service:

Service service = retrofit.create(Service.class);

Now, trying to call the data:

service.loadSizes().enqueue(new Callback<List<Size>>() {
public void onResponse(Call<List<Size>> call, Response<List<Size>> response) {
for(Size size: response.body()) {

public void onFailure(Call<List<Size>> call, Throwable t) {

What ends up with an exception:

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 18 path $[0].name

I suppose the error is caused by that, the REST API returns a response which is an array nor object.

  1. Am I correct?

  2. What is the easiest way to make this code to work?

REST service cannot be modified, so the response must stay as is.

Also, deserialization of the above json using pure GSON might be done by:

Type sizesType = new TypeToken<List<Size>>(){}.getType();
List<Size> size = new Gson().fromJson(json, sizesType);

But I have no idea how to make Retrofit 2 to use this.

Thanks in advance.

Answer Source

The funny fact is... My code is perfectly fine. At least the one presented in the question above.

I've ended up removing one line from my Size model.

As I focused on the code itself (especially Retrofit's configuration) I've totally ignored imports.

It turned out - while implementing Size model when I've started typing String class for model's fields:

  • name
  • createdAt
  • updatedAt

IntelliJ IDEA's code completion suggested me

  • not java.lang.String
  • but

what totally messed up Gson's deserialization.

When it comes to rewards...

I've decided to mark as valid my own answer. Why?

  • To ensure that, every of those developers, who will come with exactly same trouble as me - make sure you have valid imports.

Many thanks goes to gentlmen above for their great services.

As I have only one bounty I've decided reward xiaoyaoworm as his code better match my needs (I haven't written it in my question but the idea of writing such simple service - as I've presented in my question - is to hide from the end-user implementation details and not use JsonArray and such like in BNK response).

Update 1:

The only problem with xiaoyaoworm's answer is that, he suggested the Size model do not need any annotations what is totally wrong for the quoted JSON example.

For above case, exact two fields of the Size model needs annotations - created_at and updated_at.

I've even tested few versions of the converter-gson library (I saw xiaoyaoworm have used other than me) - it hasn't changed anything. Annotations were necessary.

Otherwise - again, many thanks!

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download