Spring MVC: obtener detalles de criptomonedas mediante la API REST

Las criptomonedas son un tema candente en todo el mundo. El comercio con criptomonedas tiene ventajas y desventajas. Hoy en día, las API REST son muy útiles para obtener mucha información, incluidas las criptomonedas. En este artículo, veremos una de esas llamadas a la API REST para obtener detalles de criptomonedas. Vamos a recuperar la información usando Spring MVC. Ejemplos de criptomoneda:

  • Bitcoin (BTC)
  • Litecoin (LTC)
  • Etéreo (ETH)
  • Zcash (ZEC)
  • y muchos más

Al usar la URL anterior, intentemos dar el nombre de la criptomoneda y verifiquemos el resultado.

https://api.coincap.io/v2/assets/bitcoin

Produce la salida JSON y se proporciona a continuación.

 

Ahora, para nuestra implementación Spring MVC de recuperación de llamadas API REST, mostremos los detalles a continuación como

Rank      : 1
Symbol    : BTC
Price(USD): 23016.1293786598184909

Implementación paso a paso

A través de un proyecto impulsado por Maven, la implementación se está realizando. Comencemos con la estructura del proyecto.

Estructura del proyecto:

Project Structure

 

Como es un proyecto impulsado por maven, vamos con pom.xml

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.cryptocurrency.cryptocurrency_Rest_API</groupId>
    <artifactId>cryptocurrency_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>
        <!-- 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>CryptoDetails</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>

Archivo de invocación: findCryptoDetails.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>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: #1BA330;
            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 Cryptocurrency</h5>
        <div class="form-group">
            <input id="cryptocurrency" type="text" class="form-control" placeholder="Enter cryptocurrency here..." required="required">
        </div>
        <div class="form-group">
            <button onclick="loadData()" class="btn btn-primary btn-block">Find Cryptocurrency 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>Rank        : </strong><span id="rank"></span></p>
  
              
<p><strong>Symbol     : </strong><span id="symbol"></span></p>
  
              
<p><strong>Price(USD): </strong><span id="priceUsd"></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 cryptocurrency = document.getElementById("cryptocurrency").value;
  
        if(cryptocurrency != "" && cryptocurrency != null) {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = function() {
                if (this.readyState == 4 && this.status == 200) {
                    var jsonResponse = JSON.parse(this.responseText);
                    document.getElementById("rank").innerHTML = jsonResponse.rank;
                    document.getElementById("symbol").innerHTML = jsonResponse.symbol;
                    document.getElementById("priceUsd").innerHTML = jsonResponse.priceUsd;
                    document.getElementById("loader").classList.add("hideElement");
                    document.getElementById("profile").classList.remove("hideElement");
                }
            };
            xhttp.open("GET", "getCryptocurrencyDetailsByName?cryptocurrency=" + cryptocurrency, true);
            xhttp.send();
            console.log("done");
        } else {
            console.log("Enter cryptocurrency...")
        }
    }
</script>
</html>

Este archivo JSP debe ejecutarse en cualquier servidor web como Tomcat. En la ejecución del archivo, podemos ver el siguiente resultado.

Producción:

Output

Necesitamos dar valor de criptomoneda aquí. Puede ser bitcoin o ethereum, etc.,

Vamos a comprobar si hay bitcoin

Output

 

Veamos los archivos java importantes que se usaron para el proyecto

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

CryptocurrencyController.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 CryptocurrencyController {
  
    @RequestMapping("/getCryptocurrencyDetailsByName")
    public @ResponseBody
    JsonObject getCryptocurrencyDetails(String  cryptocurrency) throws IOException {
  
        JsonObject jsonObject = new JsonObject();
        String data = getCryptocurrencyData(cryptocurrency);
          
        // Once we receive the data we need to parse that 
        // and hence these special characters has to be removed
        data = data.replaceAll("^\"|\"$", "");
        StringTokenizer jsonTokenizer = new StringTokenizer(data,",");
        String internalData[];
        String expectedCryptocurrencyOutput = null;
         
        // After parsing, retrieving Rank, Symbol and priceUsd from it
        while (jsonTokenizer.hasMoreTokens()) {  
            expectedCryptocurrencyOutput = jsonTokenizer.nextToken();
            internalData = StringUtils.split(expectedCryptocurrencyOutput,":");
            System.out.println(internalData[0]+internalData[1]);
            if (internalData[0].substring(1,internalData[0].length()-1).equalsIgnoreCase("rank")) {
                jsonObject.addProperty("rank", internalData[1].substring(1,internalData[1].length()-1));
                  
            }
            if (internalData[0].substring(1,internalData[0].length()-1).equalsIgnoreCase("symbol")) {
                jsonObject.addProperty("symbol", internalData[1].substring(1,internalData[1].length()-1));
            }
            if (internalData[0].substring(1,internalData[0].length()-1).equalsIgnoreCase("priceUsd")) {
                jsonObject.addProperty("priceUsd", internalData[1].substring(1,internalData[1].length()-1));
            }
        }
  
        jsonObject.addProperty("data", data);
  
        return jsonObject;
    }
  
    private String getCryptocurrencyData(String cryptocurrency) throws IOException {
  
        String data = null;
        StringBuilder responseData = new StringBuilder();
        JsonObject jsonObject = null;
        URL url = null;
          
        // REST API call that got used along with the search string
        url = new URL("https://api.coincap.io/v2/assets/"+cryptocurrency);
        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("data").toString();
        }
        System.out.println(data);
        return data;
    }
}

Conclusión

Las API REST son livianas, independientes, altamente escalables y flexibles. Por estas razones, con frecuencia los datos requeridos se obtienen a través de la API REST. Muchos están disponibles como llamadas de código abierto. Para algunos, necesitamos obtener una clave API adecuada (por razones de seguridad) y también existen limitaciones en el uso de esas llamadas. El que cubrimos es totalmente de código abierto y, por lo tanto, Spring Framework puede recuperar fácilmente los datos mediante un mecanismo de análisis, los datos requeridos se muestran en la pantalla.

Publicación traducida automáticamente

Artículo escrito por priyarajtt y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *