Open In App

Spring MVC – Comparison of Cryptocurrencies using REST API

REST APIS is available in plenty nowadays. As cryptocurrencies are a hot topic nowadays, there is always a need to compare the different cryptocurrencies and get the corresponding value in different currencies. As a sample, let us take a REST API call as

https://min-api.cryptocompare.com/data/price?fsym=LTC&tsyms=BTC,USD,EUR,INR

Here fym represents the cryptocurrency for which we need the current price tsyms represents another cryptocurrency in which comparison occurs USD, EUR, and INR are the currency symbols and we get the price value in the respective currency.



Output is in JSON format:

 

Let us see a few Cryptocurrencies and their symbols



Cryptocurrency

Symbol

Bitcoin BTC
Ethereum ETH
Litecoin LTC
Zcash ZEC
Iota MIOTA

Ok, now let us start preparing the Spring MVC project and render the JSON response in our desired way.

Implementation

Project Structure:

 

It is a maven-driven project

pom.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.cryptocurrencycompare.cryptocurrencycompare_Rest_API</groupId>
    <artifactId>cryptocurrencycompare_Rest_API</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>cryptocurrencycomparator</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>CryptoCompareDetails</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>

Let us start with the invoking page i.e. the JSP page where we can provide from currency and to currency




<!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>Cryptocurrency</title>
    <style type="text/css">
        .main-form, .profile-area {
            width: 500px;
        }
        .main-form {
            margin: 50px auto 0px;
        }
        .profile-area {
            margin: 10px auto;
        }
        .main-form section, .profile-area section {
            margin-bottom: 15px;
            background: #df5b47;
            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;
            font-family: verdana;
        }
        .hideElement {
            display: none;
        }
    </style>
</head>
<body>
<div class="main-form" id="main-form">
    <section>
        <h5 class="text-center">Enter a Cryptocurrency that need to be compared </h5>
        <div class="form-group">
            <input id="fsym" type="text" class="form-control" placeholder="Enter a Cryptocurrency that need to be compared..." required="required">
        </div>
        <h5 class="text-center">Enter a comparison Cryptocurrency </h5>
        <div class="form-group">
            <input id="tsyms" type="text" class="form-control" placeholder="Enter a comparison Cryptocurrency ..." required="required">
        </div>
        <div class="form-group">
            <button onclick="loadData()" class="btn btn-primary btn-block">Compare Cryptocurrencies</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>USD : <span id="USD"></span></strong></p>
 
             
<p><strong>EUR : <span id="EUR"></span></strong></p>
 
             
<p><strong>INR : <span id="INR"></span></strong></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 fsym = document.getElementById("fsym").value;
        var tsyms = document.getElementById("tsyms").value;
 
        if(fsym != "" && fsym != null && tsyms != "" && tsyms != null) {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    var jsonResponse = JSON.parse(this.responseText);
                    document.getElementById("USD").innerHTML = jsonResponse.USD;
                    document.getElementById("EUR").innerHTML = jsonResponse.EUR;
                    document.getElementById("INR").innerHTML = jsonResponse.INR;
                    document.getElementById("loader").classList.add("hideElement");
                    document.getElementById("profile").classList.remove("hideElement");
                }
            };
            xhttp.open("GET", "getCryptocurrencyComparisonDetailsByName?fsym=" + fsym + "&tsyms=" + tsyms, true);
             
            xhttp.send();
            console.log("done");
        } else {
            console.log("Enter from and to cryptocurrency...")
        }
    }
</script>
</html>

Output:

 

Let us provide from and to cryptocurrency values

 

For getting the JSON response rendered properly, we are following the controller file to perform the action via Spring. Let us see important files

AppConfig.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.cryptocurrencycompare.cryptocurrencycompare_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




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[] { "/" };
    }
  
}

Controller class

CryptocurrencyComparatorController.java




import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.StringTokenizer;
 
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
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 CryptocurrencyComparatorController {
    @RequestMapping("/getCryptocurrencyComparisonDetailsByName")
    public @ResponseBody
    JsonObject getCryptocurrencyComparatorDetails(String  fsym,String tsyms) throws IOException {
 
        JsonObject jsonObject = new JsonObject();
        jsonObject = getCryptocurrencyComparatorData(fsym,tsyms);
        String data = jsonObject.toString().replaceAll("^\"|\"$", "");
        StringTokenizer jsonTokenizer = new StringTokenizer(data,",");
        String internalData[];
        String expectedCryptocurrencyOutput = null;       
        while (jsonTokenizer.hasMoreTokens()) { 
            expectedCryptocurrencyOutput = jsonTokenizer.nextToken();
            internalData = StringUtils.split(expectedCryptocurrencyOutput,":");
            System.out.println(internalData[0]+internalData[1]);
            if (internalData[0].substring(2,internalData[0].length()-1).equalsIgnoreCase("BTC")) {
                jsonObject.addProperty("BTC",internalData[1].substring(0,internalData[1].length()));
                 
            }
            if (internalData[0].substring(1,internalData[0].length()-1).equalsIgnoreCase("USD")) {
                jsonObject.addProperty("USD",internalData[1].substring(0,internalData[1].length()));
            }
            if (internalData[0].substring(1,internalData[0].length()-1).equalsIgnoreCase("EUR")) {
                jsonObject.addProperty("EUR",internalData[1].substring(0,internalData[1].length()));
            }
            if (internalData[0].substring(1,internalData[0].length()-1).equalsIgnoreCase("INR")) {
                jsonObject.addProperty("INR",internalData[1].substring(0,internalData[1].length()-1));
            }
       
        }
        return jsonObject;
    }
 
    private JsonObject getCryptocurrencyComparatorData(String fromCryptocurrency,String toCryptocurrency) throws IOException {
        StringBuilder responseData = new StringBuilder();
        JsonObject jsonObject = null;
 
        URL url = null;
         
        url = new URL("https://min-api.cryptocompare.com/data/price?fsym="+fromCryptocurrency+"&tsyms="+toCryptocurrency+",USD,EUR,INR");
 
        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);
             
        }
        System.out.println(jsonObject);
        return jsonObject;
    }
}

Let us test the same by using JUNIT test cases and the testing is carried out by using MockMvc




import static org.junit.Assert.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.StringTokenizer;
 
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 org.springframework.util.StringUtils;
 
import com.google.gson.Gson;
import com.google.gson.JsonObject;
 
public class CryptocurrencyComparatorControllerTest {
    private MockMvc mockMvc;
 
    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.standaloneSetup(new CryptocurrencyComparatorController()).build();
    }
 
    @Test
    public void testCryptocurrencyComparisonDetails() throws Exception {
 
        // expected
        String expectedData = null;
        StringBuilder responseData = new StringBuilder();
        JsonObject expectedJsonObject = null;
        String expectedBTC = null,expectedUSD = null,expectedEUR = null,expectedINR = null;
        URL url = new URL("https://min-api.cryptocompare.com/data/price?fsym=LTC&tsyms=BTC,USD,EUR,INR");
        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);
            //expectedData = expectedJsonObject.get("data").toString();
            expectedData = expectedJsonObject.toString().replaceAll("^\"|\"$", "");
            StringTokenizer jsonTokenizer = new StringTokenizer(expectedData,",");
            String internalData[];
            String expectedCryptocurrencyOutput = null;
             
            while (jsonTokenizer.hasMoreTokens()) { 
                expectedCryptocurrencyOutput = jsonTokenizer.nextToken();
                internalData = StringUtils.split(expectedCryptocurrencyOutput,":");
                System.out.println(internalData[0]+internalData[1]);
                if (internalData[0].substring(2,internalData[0].length()-1).equalsIgnoreCase("BTC")) {
                    expectedBTC = internalData[1].substring(0,internalData[1].length());
                     
                }
                if (internalData[0].substring(1,internalData[0].length()-1).equalsIgnoreCase("USD")) {
                    expectedUSD = internalData[1].substring(0,internalData[1].length());
                }
                if (internalData[0].substring(1,internalData[0].length()-1).equalsIgnoreCase("EUR")) {
                    expectedEUR = internalData[1].substring(0,internalData[1].length());
                }
                if (internalData[0].substring(1,internalData[0].length()-1).equalsIgnoreCase("INR")) {
                    expectedINR = internalData[1].substring(0,internalData[1].length()-1);
                }
            }
             
            System.out.println(expectedBTC + " " + expectedUSD + " " + expectedEUR + " " + expectedINR);
        }
 
        // actual
        MvcResult result = mockMvc.perform(get("/getCryptocurrencyComparisonDetailsByName?fsym=LTC&tsyms=BTC"))
                .andReturn();
        String recievedResponse = result.getResponse().getContentAsString();
        JsonObject actualJsonObject = new Gson().fromJson(recievedResponse, JsonObject.class);
        String actualBTC = actualJsonObject.get("BTC").toString();
        actualBTC = actualBTC.replaceAll("^\"|\"$", "");
        String actualUSD = actualJsonObject.get("USD").toString();
        actualUSD = actualUSD.replaceAll("^\"|\"$", "");
        String actualEUR = actualJsonObject.get("EUR").toString();
        actualEUR = actualEUR.replaceAll("^\"|\"$", "");
        String actualINR = actualJsonObject.get("INR").toString();
        actualINR = actualINR.replaceAll("^\"|\"$", "");
        String internalData[];
        internalData = StringUtils.split(expectedBTC,".");
        System.out.println(internalData[0]+internalData[1]);
        assertEquals(expectedBTC, actualBTC);
        assertEquals(expectedUSD, actualUSD);
        assertEquals(expectedEUR, actualEUR);
        assertEquals(expectedINR, actualINR);
    }
 
}

Output: 

 


Article Tags :