Spring MVC - Comparison of Cryptocurrencies using REST API
Last Updated :
06 Oct, 2022
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
XML
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<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
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>Cryptocurrency</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
<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
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
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
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
Java
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:
Similar Reads
Spring MVC - @RequestParam Annotation
The @RequestParam annotation is one of the most commonly used annotations in Spring MVC for handling HTTP request parameters. @RequestParam annotation enables Spring to extract input data that may be passed as a query, form data, or any arbitrary custom data. Key features of @RequestParam annotation
5 min read
Query String and Query Parameter in Spring MVC
According to Wikipedia "A query string is a part of a uniform resource locator (URL) that assigns values to specified parameters. A query string commonly includes fields added to a base URL by a Web browser or other client application, for example as part of an HTML, choosing the appearance of a pag
6 min read
How to Make Post Request in Java Spring?
Java language is one of the most popular languages among all programming languages. There are several advantages of using the java programming language, whether for security purposes or building large distribution projects. One of the advantages of using JAVA is that Java tries to connect every conc
4 min read
How to Make Delete Request in Spring?
Java language is one of the most popular languages among all programming languages. There are several advantages of using the java programming language, whether for security purposes or building large distribution projects. One of the advantages of using JAVA is that Java tries to connect every conc
4 min read
How to Make get() Method Request in Java Spring?
Java language is one of the most popular languages among all programming languages. There are several advantages of using the java programming language, whether for security purposes or building large distribution projects. One of the advantages of using JAVA is that Java tries to connect every conc
3 min read
Spring @RequestMapping Annotation with Example
The @RequestMapping annotation in Spring MVC is one of the most important annotations used to map HTTP requests to handler methods of MVC and REST controllers. In Spring MVC applications, the DispatcherServlet (Front Controller) is responsible for routing incoming HTTP requests to the handler method
4 min read
How to Capture Data using @RequestParam Annotation in Spring?
The @RequestParam annotation enables Spring to capture input data that may be passed as a query, form data, or any arbitrary custom data. It is used to bind a web request parameter to a method parameter. Here, we are going to understand these two above lines, and we will see how we can capture data
6 min read
Spring @ResponseBody Annotation with Example
Spring Annotations allow us to configure dependencies and implement dependency injection through java programs. Those are used to provide supplemental information about a program. It does not have a direct effect on the operation of the code they annotate. It does not change the action of the compil
4 min read
Spring MVC Project - Retrieving Population, Area and Region Details using Rest API
REST API is more popular nowadays as we can able to get a variety of information like Population, Area, region, sub-region, etc., One such REST API that we are going to see here is https://restcountries.com/v3.1/capital/<any capital of a country> Example: https://restcountries.com/v3.1/capital
4 min read
Spring MVC - Last 24 Hour Cryptocurrency Data using REST API
Cryptocurrencies are a hot topic now and in the future; they may also be a payment source. Hence a lot of research is getting done. Many REST APIs are available to provide data in JSON format. We are going to see one such REST API as https://api.wazirx.com/sapi/v1/ticker/24hr?symbol=<Need to prov
5 min read