In this internet era, a lot of helper services are available in the form of REST API and mostly REST API provides us the details in the form of JSON/XML. We can use them in our applications and render the data as we like. Here is the list of a few opensource REST API URLs:
API Name | Description | URL |
---|---|---|
CoinGecko | Exchange rates | https://api.coingecko.com/api/v3/exchange_rates |
ExchangeRate-API | Exchange rates | https://open.er-api.com/v6/latest/INR |
Genderize.io | Prediction of gender based on name | https://api.genderize.io?name=rachel |
WeatherDB | To know about the weather | https://weatherdbi.herokuapp.com/data/weather/london |
Zippopotamus | Zipcode information | https://api.zippopotam.us/IN/600028 |
There are still more open-source APIs available. Here we will be learning how to extract the zip code details using Spring MVC:
REST API: http://api.zippopotam.us/IN/<Required Pincode>
Example:
http://api.zippopotam.us/IN/600028
Output: JSON
{ "post code": "600028", "country": "India", "country abbreviation": "IN", "places": [ { "place name": "Fore Shore Estate", "longitude": "80.2417", "state": "Tamil Nadu", "state abbreviation": "TN", "latitude": "13.0206" }, { "place name": "Ramakrishnanagar", "longitude": "80.2417", "state": "Tamil Nadu", "state abbreviation": "TN", "latitude": "13.0206" }, { "place name": "R A Puram Colony", "longitude": "80.2417", "state": "Tamil Nadu", "state abbreviation": "TN", "latitude": "13.0206" } ] }
Now using Spring MVC Framework, let us try to render the REST API details on the screen
Implementation:
It is as depicted Step by Step below where initially let us do see the project structure which is as follows:
A. File: pom.xml
< modelVersion >4.0.0</ modelVersion >
< groupId >com.zipCode.zipCode_RestAPI</ groupId >
< artifactId >zipCode_RestAPI</ artifactId >
< packaging >war</ packaging >
< version >0.0.1-SNAPSHOT</ version >
< name >profileGenerator</ name >
< properties >
< failOnMissingWebXml >false</ failOnMissingWebXml >
< spring-version >5.1.0.RELEASE</ spring-version >
</ properties >
< dependencies >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-webmvc</ artifactId >
< version >${spring-version}</ version >
</ dependency >
< dependency >
< groupId >org.springframework</ groupId >
< artifactId >spring-test</ artifactId >
< version >${spring-version}</ version >
</ dependency >
<!-- JSTL Dependency -->
< dependency >
< groupId >javax.servlet.jsp.jstl</ groupId >
< artifactId >javax.servlet.jsp.jstl-api</ artifactId >
< version >1.2.1</ version >
</ dependency >
< dependency >
< groupId >taglibs</ groupId >
< artifactId >standard</ artifactId >
< version >1.1.2</ version >
</ dependency >
<!-- Servlet Dependency -->
< dependency >
< groupId >javax.servlet</ groupId >
< artifactId >javax.servlet-api</ artifactId >
< version >3.1.0</ version >
< scope >provided</ scope >
</ dependency >
<!-- JSP Dependency -->
< dependency >
< groupId >javax.servlet.jsp</ groupId >
< artifactId >javax.servlet.jsp-api</ artifactId >
< version >2.3.1</ version >
< scope >provided</ scope >
</ dependency >
< dependency >
< groupId >com.google.code.gson</ groupId >
< artifactId >gson</ artifactId >
< version >2.8.6</ version >
</ dependency >
< dependency >
< groupId >commons-io</ groupId >
< artifactId >commons-io</ artifactId >
< version >2.5</ version >
</ dependency >
< dependency >
< groupId >junit</ groupId >
< artifactId >junit</ artifactId >
< version >4.12</ version >
< scope >test</ scope >
</ dependency >
</ dependencies >
< build >
< finalName >Zipcode</ finalName >
< sourceDirectory >src/main/java</ sourceDirectory >
< plugins >
< plugin >
< artifactId >maven-compiler-plugin</ artifactId >
< version >3.5.1</ version >
< configuration >
< source >1.8</ source >
< target >1.8</ target >
</ configuration >
</ plugin >
< plugin >
< groupId >org.apache.maven.plugins</ groupId >
< artifactId >maven-war-plugin</ artifactId >
< version >3.3.2</ version >
</ plugin >
< plugin >
< groupId >org.codehaus.mojo</ groupId >
< artifactId >tomcat-maven-plugin</ artifactId >
< version >1.0-beta-1</ version >
</ plugin >
</ plugins >
</ build >
</ project >
|
B. File: index.jsp
This is the page that gets rendered when the project is deployed in tomcat
<!DOCTYPE html> < html lang = "en" >
< head >
< meta charset = "utf-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" >
< meta name = "viewport" content = "width=device-width, initial-scale=1" >
< title >ZipCode</ title >
< link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" >
< style type = "text/css" >
.main-form, .profile-area {
width: 500px;
background: #FF5733;
}
.main-form {
margin: 50px auto 0px;
}
.profile-area {
margin: 10px auto;
}
.main-form section, .profile-area section {
margin-bottom: 15px;
background: #f7f7f7;
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
}
.main-form section {
padding: 30px;
}
.profile-area section {
padding: 30px 30px 30px;
}
.profile-area section > div {
text-align: center;
}
.main-form h3 {
margin: 0 0 15px;
}
.form-control, .btn {
min-height: 38px;
border-radius: 2px;
}
.btn {
font-size: 15px;
font-weight: bold;
}
.hideElement {
display: none;
}
</ style >
</ head >
< body >
< div class = "main-form" id = "main-form" >
< section >
< h5 class = "text-center" >Enter your zipcode</ h5 >
< div class = "form-group" >
< input id = "zipcode" type = "text" class = "form-control" placeholder = "Enter zipcode here..." required = "required" >
</ div >
< div class = "form-group" >
< button onclick = "loadData()" class = "btn btn-primary btn-block" >Find Area Details</ button >
</ div >
</ section >
</ div >
< div class = "profile-area hideElement" id = "profile-area" >
< section >
< div id = "loader" class = "hideElement" >
< div class = "spinner-border" role = "status" >
< span class = "sr-only" >Loading...</ span >
</ div >
</ div >
< div id = "profile" class = "hideElement" >
< br >< br >
< p >< strong >Country : </ strong >< span id = "country" ></ span ></ p >
< p >< strong >State : </ strong >< span id = "statename" ></ span ></ p >
< p >< strong >Localities : </ strong >< span id = "associatedplaces" ></ span ></ p >
< p >< strong >Latitude : </ strong >< span id = "associatedlatitude" ></ span ></ p >
< p >< strong >Longitude : </ strong >< span id = "associatedlongitude" ></ span ></ p >
</ div >
</ section >
</ div >
</ body >
< script >
function loadData() {
document.getElementById("profile-area").classList.remove("hideElement");
document.getElementById("loader").classList.remove("hideElement");
document.getElementById("profile").classList.add("hideElement");
var zipCode = document.getElementById("zipcode").value;
if(zipCode != "" && zipCode != null) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var jsonResponse = JSON.parse(this.responseText);
document.getElementById("country").innerHTML = jsonResponse.country;
document.getElementById("statename").innerHTML = jsonResponse.statename;
document.getElementById("associatedplaces").innerHTML = jsonResponse.associatedplaces;
document.getElementById("associatedlatitude").innerHTML = jsonResponse.associatedlatitude;
document.getElementById("associatedlongitude").innerHTML = jsonResponse.associatedlongitude;
document.getElementById("loader").classList.add("hideElement");
document.getElementById("profile").classList.remove("hideElement");
}
};
xhttp.open("GET", "getLocalityDetailsByZipCode?zipCode=" + zipCode, true);
xhttp.send();
console.log("done");
} else {
console.log("Enter zipcode...")
}
}
</ script >
</ html >
|
Output:
On entering any valid zip code. For example 600028, name in the input box, we will get the below details.
Execution Process: From the JSP page, a “GET” method is invoked with the search string and it is redirected to the Spring Controller class, where the REST API URL, <a target="_blank" rel="noopener noreferrer nofollow" href="http://api.zippopotam.us/IN/http://api.zippopotam.us/IN/<valid zipcode> is invoked and it will create the JSON object as given above, From that, we are taking “country”, “state”,”latitude”,”longitude” and “localities” values.
Country : India State : Tamil Nadu Localities : [Fore Shore Estate, Ramakrishnanagar, R A Puram Colony] Latitude : [13.0206, 13.0206, 13.0206] Longitude : [80.2417, 80.2417, 80.2417]
Output: Screen
Required code for retrieving the data and parsing the JSON output is as follows. Important necessary files to achieve the flow
File: AppConfig.java
// Java Program to Illustrate Application // configuration Class // Importing required classes import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
// Annotations @Configuration @EnableWebMvc @ComponentScan (basePackages
= { "com.zipCode.zipCode_RestAPI" })
// Class public class AppConfig {
@Bean public InternalResourceViewResolver resolver()
{
InternalResourceViewResolver resolver
= new InternalResourceViewResolver();
resolver.setViewClass(JstlView. class );
resolver.setPrefix( "/" );
resolver.setSuffix( ".jsp" );
return resolver;
}
} |
File: SpringMvcDispatcherServletInitializer.java
// Java Program to Illustrate // SpringMvcDispatcherServletInitializer Class // Importing required classes import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
// Class public class SpringMvcDispatcherServletInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer {
// Method 1
@Override protected Class<?>[] getRootConfigClasses()
{
return null ;
}
// Method 2
@Override protected Class<?>[] getServletConfigClasses()
{
return new Class[] { AppConfig. class };
}
// Method 3
@Override protected String[] getServletMappings()
{
return new String[] { "/" };
}
} |
File: ZipCodeController.java
// Java Program to Illustrate ZipCodeController Class // Importing required classes import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
// Annotation @Controller // Class public class ZipCodeController {
// Method 1
@RequestMapping ( "/getLocalityDetailsByZipCode" )
public @ResponseBody
JsonObject getLocalityDetailsByZipCode(String zipCode)
throws IOException
{
JsonObject jsonObject = new JsonObject();
jsonObject = getLocalityDetailsByZip(zipCode);
// Parsing the JSONObject
JsonObject finalJsonObject = new JsonObject();
String country
= jsonObject.get( "country" ).toString();
country = country.replaceAll( "^\"|\"$" , "" );
JsonArray jsonPlacesArray = null ;
ArrayList placesList = new ArrayList();
ArrayList stateList = new ArrayList();
ArrayList latitudeList = new ArrayList();
ArrayList longitudeList = new ArrayList();
// Places data is available as JSONArray
jsonPlacesArray
= jsonObject.get( "places" ).getAsJsonArray();
// It is iterated
Iterator<JsonElement> objectIterator
= jsonPlacesArray.iterator();
while (objectIterator.hasNext()) {
JsonElement object = objectIterator.next();
JsonObject jObj = object.getAsJsonObject();
System.out.println(
jObj.get( "place name" ).toString()
+ jObj.get( "state" ).toString());
placesList.add(jObj.get( "place name" )
.toString()
.replaceAll( "^\"|\"$" , "" ));
stateList.add(
jObj.get( "state" ).toString().replaceAll(
"^\"|\"$" , "" ));
latitudeList.add(
jObj.get( "latitude" )
.toString()
.replaceAll( "^\"|\"$" , "" ));
longitudeList.add(
jObj.get( "longitude" )
.toString()
.replaceAll( "^\"|\"$" , "" ));
}
finalJsonObject.addProperty( "country" , country);
finalJsonObject.addProperty( "associatedplaces" ,
placesList.toString());
finalJsonObject.addProperty( "associatedplacessize" ,
placesList.size());
finalJsonObject.addProperty( "state" ,
stateList.toString());
finalJsonObject.addProperty(
"statename" , stateList.get( 0 ).toString());
finalJsonObject.addProperty(
"associatedlatitude" , latitudeList.toString());
finalJsonObject.addProperty(
"associatedlatitudesize" , latitudeList.size());
finalJsonObject.addProperty(
"associatedlongitude" ,
longitudeList.toString());
finalJsonObject.addProperty(
"associatedlongitudesize" ,
longitudeList.size());
return finalJsonObject;
}
// Method 2
private JsonObject
getLocalityDetailsByZip(String zipCode)
throws IOException
{
String data = null ;
StringBuilder responseData = new StringBuilder();
JsonObject jsonObject = null ;
URL url = null ;
+ zipCode);
HttpURLConnection con
= (HttpURLConnection)url.openConnection();
con.setRequestMethod( "GET" );
con.setRequestProperty( "User-Agent" , "Mozilla/5.0" );
int responseCode = con.getResponseCode();
System.out.println(
"\nSending 'GET' request to URL : " + url);
// System.out.println("Response Code : " +
// responseCode);
// Try block to check for exceptions
try (BufferedReader in
= new BufferedReader( new InputStreamReader(
con.getInputStream()))) {
String line;
while ((line = in.readLine()) != null ) {
responseData.append(line);
}
jsonObject = new Gson().fromJson(
responseData.toString(), JsonObject. class );
}
// System.out.println(data);
return jsonObject;
}
} |
Conclusion: This process of code is required for retrieving any REST API call. We need to know whether REST API provides either JSONObject/JSONArray and accordingly we have to parse the data.