Open In App

Get Time Zone by Providing Latitude and Longitude using Spring MVC and REST API

Improve
Improve
Like Article
Like
Save
Share
Report

Spring MVC Framework follows the Model-View-Controller design pattern. It is used to develop web applications. It works around DispatcherServlet. DispatcherServlet handles all the HTTP requests and responses. In this article, we are going to see about a REST API call to find the coordinates for the given latitude and longitude. Each and every area in the globe is identified by means of latitude and longitude. For example, India, Asia/Kolkata timezone can be identified by means of

Latitude -> 21.7679
Longitude -> 78.8718

Corresponding REST API call:

https://api.wheretheiss.at/v1/coordinates/<Latitude,Longitude>

Here in the place of Latitude, we need to substitute the proper Latitude value. In the place of Longitude, we need to substitute the proper Longitude value

Example:

https://api.wheretheiss.at/v1/coordinates/21.7679,78.8718

Output:

REST API call provides JSON response.

JSON response

 

Via Spring MVC framework, let us parse the REST API call JSON response and render the necessary elements. It can be done via a maven-driven project. Let us see how to do that.

Step by Step Implementation

Project Structure for bringing the timezone value for a given Latitude and Longitude. Let us cover the required JUNIT test cases also for it.

Project Structure

 

Let us check the important files of the project

getTimeZone.jsp

HTML




<!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>WTIA</title>
    <style type="text/css">
        .main-form, .profile-area {
            width: 640px;
        }
        .main-form {
            margin: 50px auto 0px;
        }
        .profile-area {
            margin: 10px auto;
        }
        .main-form section, .profile-area section {
            margin-bottom: 15px;
            background: #c080c0;
            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: 20px;
            font-weight: inherit;
            font-family: sans-serif;
        }
        .hideElement {
            display: none;
        }
    </style>
</head>
<body>
<div class="main-form" id="main-form">
    <section>
        <h5 class="text-center">Enter Latitude</h5>
        <div class="form-group">
            <input id="latitude" type="text" class="form-control" placeholder="Enter latitude here..." required="required">
        </div>
        <h5 class="text-center">Enter Longitude</h5>
        <div class="form-group">
            <input id="longitude" type="text" class="form-control" placeholder="Enter longitude here..." required="required">
        </div>
        <div class="form-group">
            <button onclick="loadData()" class="btn btn-primary btn-block">Find TimeZone</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>TimeZone: <span id="timezone_id"></strong></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 latitude = document.getElementById("latitude").value;
        var longitude = document.getElementById("longitude").value;
 
 
        if(latitude != "" && latitude != null && longitude != "" && longitude != null) {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    var jsonResponse = JSON.parse(this.responseText);
                    document.getElementById("timezone_id").innerHTML = jsonResponse.timezone_id;
                    //document.getElementById("age").innerHTML = jsonResponse.age;
                    document.getElementById("loader").classList.add("hideElement");
                    document.getElementById("profile").classList.remove("hideElement");
                }
            };
            xhttp.open("GET", "getSateliteDetailsByLatAndLon?latitude=" + latitude + "&longitude=" + longitude, true);
            xhttp.send();
            console.log("done");
        } else {
            console.log("Enter latitude and lonitude...")
        }
    }
</script>
</html>


Output:

UI Output

 

On entering the correct latitude and longitude, we will get the below screens

UI Output

 

Example 2:

JSON response is given parallely

 

Let us see the important files required for the project. As it is the maven project, let us start with 

pom.xml

XML




    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                        http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.wtia.WTIA_Rest_API</groupId>
    <artifactId>WTIA_Rest_API</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>profileGenerator</name>
    <url>http://maven.apache.org</url>
    <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>Timezone</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>
            <!-- This should be added to overcome Could not initialize class
                  org.apache.maven.plugin.war.util.WebappStructureSerializer -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.2</version>
            </plugin>
        </plugins>
    </build>
</project>


Java files:

AppConfig.java

Java




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;
 
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.wtia.WTIA_Rest_API" })
public class AppConfig {
    @Bean
    public InternalResourceViewResolver resolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setViewClass(JstlView.class);
        resolver.setPrefix("/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}


SpringMvcDispatcherServletInitializer.java

Java




import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
 
public class SpringMvcDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
  
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }
  
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { AppConfig.class };
    }
  
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
  
}


WtiaController.java

Java




import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
 
@Controller
public class WtiaController {
 
    @RequestMapping("/getSateliteDetailsByLatAndLon")
    public @ResponseBody
    JsonObject getSateliteDetails(String  latitude,String longitude ) throws IOException {
        JsonObject jsonObject = new JsonObject();
        String timezoneId = getSateliteData(latitude,longitude);
        timezoneId = timezoneId.replaceAll("^\"|\"$", "");
        jsonObject.addProperty("timezone_id", timezoneId);
        return jsonObject;
    }
 
    private String getSateliteData(String latitude,String longitude) throws IOException {
        String data = null;
        StringBuilder responseData = new StringBuilder();
        JsonObject jsonObject = null;
        URL url = null;     
        url = new URL("https://api.wheretheiss.at/v1/coordinates/"+latitude + "," + longitude);
        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 (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);         
            data = jsonObject.get("timezone_id").toString();
        }
        System.out.println(data);
        return data;
    }
}


Flow of the Program:

When “getTimeZone.jsp” is called and the proper latitude and longitude are given, it is sent to the “WtiaController.java” file and the GET request mapping is checked against “getSateliteDetailsByLatAndLon” and from jsp, latitude, and longitude are substituted, it will call the REST API call

https://api.wheretheiss.at/v1/coordinates/<Latitude,Longitude>
--Input latitude and longitude are getting substituted here

Then JSON response is parsed and the necessary details like timezone_id or country_code will be displayed. Necessary JUnit test case file

WtiaControllerTest.java

Java




package com.wtia.WTIA_Rest_API.controller;
 
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 
public class WtiaControllerTest {
     
    // It is available in
    // org.springframework.test.web.servlet.MockMvc
    private MockMvc mockMvc;
 
    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.standaloneSetup(new WtiaController()).build();
    }
 
    @Test
    public void testWTIADetails() throws Exception {
         
        // expected
        String expectedTimezoneId = null;
        StringBuilder responseData = new StringBuilder();
        JsonObject expectedJsonObject = null;
        URL url = new URL("https://api.wheretheiss.at/v1/coordinates/50.11496269845,118.07900427317");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("User-Agent", "Mozilla/5.0");
        try (BufferedReader in = new BufferedReader(
                new InputStreamReader(con.getInputStream()))) {
 
            String line;
 
            while ((line = in.readLine()) != null) {
                responseData.append(line);
            }
 
            expectedJsonObject = new Gson().fromJson(responseData.toString(), JsonObject.class);
            expectedTimezoneId = expectedJsonObject.get("timezone_id").toString();
            expectedTimezoneId = expectedTimezoneId.replaceAll("^\"|\"$", "");
 
        }
 
        // actual
        MvcResult result = mockMvc.perform(get("/getSateliteDetailsByLatAndLon?latitude=50.11496269845&longitude=118.07900427317"))
                .andReturn();
        String receivedResponse = result.getResponse().getContentAsString();
        JsonObject actualJsonObject = new Gson().fromJson(receivedResponse, JsonObject.class);
        String actualTimezoneId = actualJsonObject.get("timezone_id").toString();
        actualTimezoneId = actualTimezoneId.replaceAll("^\"|\"$", "");
         
        // checking the expectedtimezone and actualtimezone
        assertEquals(expectedTimezoneId, actualTimezoneId);
    }
}


We have to run this file as JUnit test like this.

JUnit Test Run

 

Output:

JUnit Test Output

 

Conclusion

REST APIs are awesome. We can get valuable information from them. As it is producing JSON responses, they are lightweight, easily portable, and adaptable to any technology.



Last Updated : 22 Aug, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads