This post will show you how to consume a RestFul API in Spring through RestTemplate
We will be consuming data from the Google Books API, This URL returns of Books for ISBN 9380658745. The result that is returned looks like this
{
"kind": "books#volumes",
"totalItems": 1,
"items": [
{
"kind": "books#volume",
"id": "Ewy-RQs641sC",
"etag": "ZGdQqX4j0UM",
"selfLink": "https://www.googleapis.com/books/v1/volumes/Ewy-RQs641sC",
"volumeInfo": {
"title": "Immortals of Meluha",
"authors": [
"Tripathi, Amish"
],
"publisher": "Westland",
"publishedDate": "2011",
"description": "This is the first book in a trilogy on Shiva, the simple man whose karma re-cast his as our Mahadev, the God of Gods.",
"industryIdentifiers": [
{
"type": "ISBN_13",
"identifier": "9789380658742"
},
{
"type": "ISBN_10",
"identifier": "9380658745"
}
],
"readingModes": {
"text": true,
"image": true
},
"pageCount": 411,
"printType": "BOOK",
"categories": [
"Fiction"
],
"averageRating": 4.0,
"ratingsCount": 36,
"maturityRating": "NOT_MATURE",
"allowAnonLogging": false,
"contentVersion": "2.6.6.0.preview.3",
"imageLinks": {
"smallThumbnail": "http://bks4.books.google.co.in/books/content?id=Ewy-RQs641sC&printsec=frontcover&img=1&zoom=5&edge=curl&source=gbs_api",
"thumbnail": "http://bks4.books.google.co.in/books/content?id=Ewy-RQs641sC&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api"
},
"language": "en",
"previewLink": "http://books.google.co.in/books?id=Ewy-RQs641sC&printsec=frontcover&dq=isbn:9380658745&hl=&cd=1&source=gbs_api",
"infoLink": "http://books.google.co.in/books?id=Ewy-RQs641sC&dq=isbn:9380658745&hl=&source=gbs_api",
"canonicalVolumeLink": "http://books.google.co.in/books/about/Immortals_of_Meluha.html?hl=&id=Ewy-RQs641sC"
},
"saleInfo": {
"country": "IN",
"saleability": "FOR_SALE",
"isEbook": true,
"listPrice": {
"amount": 295.0,
"currencyCode": "INR"
},
"retailPrice": {
"amount": 118.0,
"currencyCode": "INR"
},
"buyLink": "http://books.google.co.in/books?id=Ewy-RQs641sC&dq=isbn:9380658745&hl=&buy=&source=gbs_api",
"offers": [
{
"finskyOfferType": 1,
"listPrice": {
"amountInMicros": 2.95E8,
"currencyCode": "INR"
},
"retailPrice": {
"amountInMicros": 1.18E8,
"currencyCode": "INR"
}
}
]
},
"accessInfo": {
"country": "IN",
"viewability": "PARTIAL",
"embeddable": true,
"publicDomain": false,
"textToSpeechPermission": "ALLOWED",
"epub": {
"isAvailable": true,
"acsTokenLink": "http://books.google.co.in/books/download/Immortals_of_Meluha-sample-epub.acsm?id=Ewy-RQs641sC&format=epub&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
},
"pdf": {
"isAvailable": true,
"acsTokenLink": "http://books.google.co.in/books/download/Immortals_of_Meluha-sample-pdf.acsm?id=Ewy-RQs641sC&format=pdf&output=acs4_fulfillment_token&dl_type=sample&source=gbs_api"
},
"webReaderLink": "http://books.google.co.in/books/reader?id=Ewy-RQs641sC&hl=&printsec=frontcover&output=reader&source=gbs_api",
"accessViewStatus": "SAMPLE",
"quoteSharingAllowed": false
},
"searchInfo": {
"textSnippet": "This is the first book in a trilogy on Shiva, the simple man whose karma re-cast his as our Mahadev, the God of Gods."
}
}
]
}
Spring provides out of the box Methods to fetch the details from the REST API. Following are the methods provided by the RestTemplate to make a GET call on the REST API.
getForObject(java.lang.String, java.lang.Class, java.lang.Object...)
getForEntity(java.lang.String, java.lang.Class, java.lang.Object...)
Following is the method that demonstrates how to use getForEntity method, which returns the ResponseEntity, it consist of all the Header message and it needs to be provided with the Class Object to which JSON details will be mapped.
public void getGoogleDetailISBN(){
String isbn = "9380658745";
RestTemplate restTemplate = new RestTemplate();
ResponseEntity entity = restTemplate.getForEntity("https://www.googleapis.com/books/v1/volumes?q=isbn:"+isbn, GBWrapper.class);
System.out.println(entity.getBody().getItems()[0].getVolumeInfo().getPublisher());
}
As you look into the API results it consist of 'kind' and 'totalItems' and an array of number of "items" returned by the search.
Each 'item' contains volumeInfo , SaleInfo and accessInfo Objects.
I am interested mainly in the volumeInfo details, But to reach that I will have to create wrapper classes, so that Jackson will be able to convert the JSON data into the POJO classes seamlessly.
The first is the GBWrapper class that contains the array of GBItemsWrapper. As Jackson converts the data, it maps the items data into the GBItemsWrapper.
package balloons.books.model;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown=true)
public class GBWrapper {
private int totalItems;
private GBItemsWrapper[] items;
public int getTotalItems() {
return totalItems;
}
public void setTotalItems(int totalItems) {
this.totalItems = totalItems;
}
public GBItemsWrapper[] getItems() {
return items;
}
public void setItems(GBItemsWrapper[] items) {
this.items = items;
}
}
@JsonIgnoreProperties denotes that we may only interested in some JSON property, and other property will be ignored.
GBItemsWrapper.java
package balloons.books.model;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown=true)
public class GBItemsWrapper {
private GBVolumeInfoWrapper volumeInfo;
public GBVolumeInfoWrapper getVolumeInfo() {
return volumeInfo;
}
public void setVolumeInfo(GBVolumeInfoWrapper volumeInfo) {
this.volumeInfo = volumeInfo;
}
}
Finally the GBVolumeInfoWrapper.java Class that will contain the VolumeInfo details that I am interested in
package balloons.books.model;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown=true)
public class GBVolumeInfoWrapper {
private String title;
private String publisher;
private String publishedDate;
private String[] authors;
private String description;
private int pageCount;
private int printType;
private String[] categories;
private Map<String, String> imageLinks = new HashMap<String, String>();
private String language;
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
}