Search code examples
javajsonparsingjersey-clientgoogle-books

Parsing JSON with Jackson return null


I'm training my self on java using API. The subject of my exercise is to ask google books API in order to take some infos about books. I use Jersey as a client and Jackson to parse the JSON.

My problem is that when i run the JerseyVolumeGet() , the response is this one :

Volume{title='null', numberOfPages=null, author='null'}

Why ? Where is my mistake ? I suspect i get wrong when parsing the JSON but don't see where exactly..

Here my getClass ( the search url is barcoded , it's not a problem for me)

public class JerseyVolumeGet {
    public static void main(String[] args) {
        try {

            Client client = Client.create();

            WebResource webResource = client
                    .resource("https://www.googleapis.com/books/v1/volumes?q=1984");

            ClientResponse response = webResource.accept("application/json")
                    .get(ClientResponse.class);

            if (response.getStatus() != 200) {
                throw new RuntimeException("Noob you Failed : HTTP error code : "
                        + response.getStatus());
            }

            String output = response.getEntity(String.class);

            // read from file, convert it to user class
            ObjectMapper mapper = new ObjectMapper();
            Volume volume = mapper.readValue(output, Volume.class);


            // display to console
            System.out.println(volume);


        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

Here the JSON result of my query :

{
 "kind": "books#volumes",
 "totalItems": 641,
 "items": [
  {
   "kind": "books#volume",
   "id": "RY8yQWeDVFYC",
   "etag": "Lf0P50PVz9c",
   "selfLink": "https://www.googleapis.com/books/v1/volumes/RY8yQWeDVFYC",
   "volumeInfo": {
    "title": "(1984).",
    "subtitle": "",
    "authors": [
     "Guy Serbat",
     "Jean Taillardat",
     "Gilbert Lazard"
    ],
    "publisher": "Peeters Publishers",
    "publishedDate": "1984-01-01",
    "description": "(Peeters 1984)",
    "industryIdentifiers": [
     {
      "type": "ISBN_10",
      "identifier": "2904685030"
     },
     {
      "type": "ISBN_13",
      "identifier": "9782904685033"
     }
    ],
    "readingModes": {
     "text": false,
     "image": true
    },
    "pageCount": 280,
    "printType": "BOOK",
    "categories": [
     "Language Arts & Disciplines"
    ],
    "contentVersion": "1.1.1.0.preview.1",
    "imageLinks": {
     "smallThumbnail": "http://bks9.books.google.fr/books?id=RY8yQWeDVFYC&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
     "thumbnail": "http://bks9.books.google.fr/books?id=RY8yQWeDVFYC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
    },
    "language": "fr",
    "previewLink": "http://books.google.fr/books?id=RY8yQWeDVFYC&printsec=frontcover&dq=1984&hl=&cd=1&source=gbs_api",
    "infoLink": "http://books.google.fr/books?id=RY8yQWeDVFYC&dq=1984&hl=&source=gbs_api",
    "canonicalVolumeLink": "http://books.google.fr/books/about/1984.html?hl=&id=RY8yQWeDVFYC"
   },
   "saleInfo": {
    "country": "FR",
    "saleability": "NOT_FOR_SALE",
    "isEbook": false
   },
   "accessInfo": {
    "country": "FR",
    "viewability": "PARTIAL",
    "embeddable": true,
    "publicDomain": false,
    "textToSpeechPermission": "ALLOWED",
    "epub": {
     "isAvailable": false
    },
    "pdf": {
     "isAvailable": false
    },
    "webReaderLink": "http://books.google.fr/books/reader?id=RY8yQWeDVFYC&hl=&printsec=frontcover&output=reader&source=gbs_api",
    "accessViewStatus": "SAMPLE",
    "quoteSharingAllowed": false
   },
   "searchInfo": {
    "textSnippet": "(Peeters 1984)"
   }
  },
more items...
}

Then , i've a Volume.class like that :

@JsonIgnoreProperties(ignoreUnknown=true)
public class Volume {
    @JsonProperty("title")
    String title;
    @JsonProperty("pageCount")
    Integer pageCount;
    @JsonProperty("authors")
    String authors;

getters , setters and toString..

Solution

  • You need to model the full JSON structure, something like this:

    public class BookData {
        String kind;
        Integer totalItems;
        List<Item> items;
    }
    
    public class Item {
        String kind;
        String id;
        //...
        Volume volumeInfo;
    }
    

    Then you can use ObjectMapper to read the BookData:

    BookData bookData = new ObjectMapper().readValue(output, BookData.class);
    

    And pull out the Volume info from each Item in the BookData.