3

I have problems parsing two different JSON responses.

1: This is the JSON response I get from a RESTful API:

{
  "gear": [
    {
      "idGear": "1",
      "name": "Nosilec za kolesa",
      "year": "2005",
      "price": "777.0"
    }, {
      "idGear": "2",
      "name": "Stresni nosilci",
      "year": "1983",
      "price": "40.0"
    }
  ]
}

2: This response I get from my testing client. I was added some values to the list and then I used gson.toJson for testing output.

[
  {
    "idGear": "1",
    "name": "lala",
    "year": 2000,
    "price": 15.0
  }, {
    "idGear": "2",
    "name": "lala2",
    "year": 2000,
    "price": 125.0
  }
]

They are both valid, but the second one was successfully deserialize to object like this:

Type listType = new TypeToken<List<Gear>>() {}.getType();
List<Gear> gears= (List<Gear>) gson.fromJson(json, listType); 

With the first one, I was trying to deserialize the same way but I get error.


EDIT

API Method:

@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Gear> getGear() {
  List<Gear> gears = gearDAO.getGears();
  if (!gears.isEmpty()) {
    return gears;
  } else
    throw new RuntimeException("No gears");
}

CLIENT serialization code:

List<Gear> list = new ArrayList<Gear>();
Gear o = new Gear();
o.setPrice(15);
o.setYear(2000);
o.setName("asds");
Type listTypes = new TypeToken<List<Gear>>() {}.getType();
gson.toJson(list, listTypes);
MikO
  • 18,243
  • 12
  • 77
  • 109
Mitja Rogl
  • 894
  • 9
  • 22
  • 39

1 Answers1

10

The JSON responses are different!

  • The first one is an object, surrounded by { }, which contains a field "gear" that is in turn a list of objects, surrounded by [ ].

  • The second one is directly a list of objects, because it's surrounded by [ ]. Namely, the whole 2nd response is equivalent to the field in the 1st response.

So, obviously they can't be parsed in the same way...

The 2nd one is being parsed correctly because you are using a List and it is a list. But for the 1st one you need another class that contains a field that contains in turn a list... That is, you just need to create a class structure that represents your JSON responses...

public class Response {    
    private List<Gear> gears;        
    //getters & setters
}

Now you can parse your 1st response with:

Gson gson = new Gson();
Response response = gson.fromJson(json, Response .class);
List<Gear> gears = response.getGears();

I suggest you to take a brief look at json.org in order to understand JSON syntax, which is pretty simple... Basically these are the possible JSON elements:

object
    {}
    { members } 
members
    pair
    pair , members
pair
    string : value
array
    []
    [ elements ]
elements
    value
    value , elements
value
    string
    number
    object
    array
    true
    false
    null 
MikO
  • 18,243
  • 12
  • 77
  • 109
  • Both restful api and testClient are returning `List` but responses are different. I don't know why? – Mitja Rogl May 13 '13 at 11:43
  • Well, as I said, the API is NOT returning just a `List`... it's returning an object that contains a field which is a `List`. In fact the concrete datatype it's returning is a `Map` but not to a `List`... I assume this API is not controlled by you, right? It's quite usual that REST APIs return data in this way, always contained in an object with a field `"response"` (in your case `"gears"`) or something like that... – MikO May 13 '13 at 11:51
  • The API is mine, and it is returning List, so that's why I confused. – Mitja Rogl May 13 '13 at 12:34
  • Then I'm confused too ;) please include the code of the API and the test client where you serialize the objects into JSON and I may find the difference... – MikO May 13 '13 at 12:40
  • 1
    In your client you serialize your `List` using Gson (`gson.toJson()`), so the result is the expected. However, in your API method, you don't serialize the `List` with Gson... I'm not an expert in JAX-RS, but I guess the serialization is performed by some JAX-RS tool that produces a different JSON for the same structure... It's not incorrect, but it's just another respresentation of the same info, and as I said, it's quite common in REST services to return the data like that, contained in a field `"response"` or wahtever name... I can't help you too much with JAX-RS... – MikO May 13 '13 at 13:25