You are currently viewing How to Build a Real-Time Currency Converter in Java

How to Build a Real-Time Currency Converter in Java

In today’s interconnected world, currency conversion is an essential task for many applications. In this blog post, we will explore how to build a currency converter in Java using the ExchangeRate-API. We’ll leverage the Apache HttpClient library and Google’s Gson library to make HTTP requests and handle JSON responses. So, let’s dive into the code and see how it all works together.

Setting up the Dependencies

To get started, we need to include the necessary dependencies in our Java project. We’ll use Apache HttpClient, which can be downloaded here and Gson libraries, download here. Make sure to have them added to your project’s classpath.

Creating the CurrencyConverter Class

We begin by creating a CurrencyConverter class that will serve as the main component for interacting with the ExchangeRate-API. The class contains various methods to perform different currency-related operations.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.apache.hc.core5.net.URIBuilder;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

public class CurrencyConverter {

    private static final String API_BASE_URI = "http://api.exchangerate.host";
    private final String accesskey;

    public CurrencyConverter(String accessKey) {
        this.accesskey = accessKey;
    }

    /*
     * Retrieves the most recent exchange rate data
     */
    public JsonElement live(BasicNameValuePair... nameValuePairs) throws URISyntaxException, IOException {
        return this.apiRequest("/live", nameValuePairs);
    }

    /*
     * Convert one currency to another
     */
    public JsonElement convert(String from, String to, String amount, BasicNameValuePair... nameValuePairs) throws URISyntaxException, IOException {

        List<BasicNameValuePair> pairs = new ArrayList<>(Arrays.asList(
                new BasicNameValuePair("from", from),
                new BasicNameValuePair("to", to),
                new BasicNameValuePair("amount", amount)
        ));

        return this.apiRequest("/convert", this.getParameters(pairs, nameValuePairs));

    }

    /*
     * Retrieves historical rates for a specific day
     */
    public JsonElement historical(String date, BasicNameValuePair... nameValuePairs) throws URISyntaxException, IOException {

        List<BasicNameValuePair> pairs = new ArrayList<>(List.of(
                new BasicNameValuePair("date", date)
        ));

        return this.apiRequest("/historical", this.getParameters(pairs, nameValuePairs));
    }

    /*
     * Retrieves exchange rates for a specific period of time
     */
    public JsonElement timeframe(String startDate, String endDate, BasicNameValuePair... nameValuePairs) throws URISyntaxException, IOException {

        List<BasicNameValuePair> pairs = new ArrayList<>(Arrays.asList(
                new BasicNameValuePair("start_date", startDate),
                new BasicNameValuePair("end_date", endDate)
        ));

        return this.apiRequest("/timeframe", this.getParameters(pairs, nameValuePairs));

    }

    /*
     * Retrieves any currency's change parameters (margin, percentage)
     */
    public JsonElement change(String currencies, BasicNameValuePair... nameValuePairs) throws URISyntaxException, IOException {

        List<BasicNameValuePair> pairs = new ArrayList<>(List.of(
                new BasicNameValuePair("currencies", currencies)
        ));

        return this.apiRequest("/change", this.getParameters(pairs, nameValuePairs));

    }

    /*
     * Retrieves all supported currencies
     */
    public JsonElement list(BasicNameValuePair... nameValuePairs) throws URISyntaxException, IOException {
        return this.apiRequest("/list", nameValuePairs);
    }

    private BasicNameValuePair[] getParameters(List<BasicNameValuePair> pairList, BasicNameValuePair... nameValuePairs) {

        pairList.addAll(Arrays.asList(nameValuePairs));

        return pairList.toArray(new BasicNameValuePair[0]);

    }

    private JsonElement apiRequest(String path, BasicNameValuePair... nameValuePairs) throws URISyntaxException, IOException {

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

            URI uri = this.buildURI(API_BASE_URI + path, nameValuePairs);

            HttpGet request = new HttpGet(uri);

            AtomicReference<JsonElement> element = new AtomicReference<>();

            // Execute the HTTP request and capture the response
            httpClient.execute(request, response -> {
                element.set(this.getJsonElement(response));
                return response;
            });

            return element.get();

        }

    }

    private URI buildURI(String uri, BasicNameValuePair[] nameValuePairs) throws URISyntaxException {

        URIBuilder uriBuilder = new URIBuilder(uri);

        for (BasicNameValuePair nameValuePair : nameValuePairs) {
            uriBuilder.addParameter(nameValuePair.getName(), nameValuePair.getValue());
        }

        uriBuilder.addParameter("access_key", this.accesskey);

        // Build the URI with the specified parameters
        return uriBuilder.build();

    }

    private JsonElement getJsonElement(ClassicHttpResponse response) throws IOException, ParseException {

        HttpEntity entity = response.getEntity();

        String responseBody = EntityUtils.toString(entity);

        Gson gson = new GsonBuilder().create();

        // Parse the JSON response to a JsonElement object
        return gson.fromJson(responseBody, JsonElement.class);

    }

}

Retrieving Latest Currency Exchange Rates

The live method sends an HTTP GET request to the ExchangeRate-API’s “/live” endpoint. It retrieves the most recent currency exchange rates. We utilize the apiRequest method to handle the HTTP request and response, and the Gson library to parse the JSON response into a JsonElement object.

package com.coderscratchpad.javatutorial;

import com.google.gson.JsonElement;
import org.apache.hc.core5.http.message.BasicNameValuePair;

import java.io.IOException;

import java.net.URISyntaxException;

public class Main {

    public static void main(final String[] args) {

        try {
            
            // Be sure to provide your own API access key, 
            // note I used the Free Subscription Plan for this tutorial
            CurrencyConverter converter = new CurrencyConverter("5edf6c440cdaa42336d949******");

            // Basic usage of the live method
            // Set US dollar as the base currency
            JsonElement live  = converter.live(new BasicNameValuePair("base", "USD"));

            // Prints the most recent exchange rates
            System.out.println(live.getAsJsonObject());

        } catch (URISyntaxException | IOException exception) {

            System.out.println(exception.getMessage());

        }

    }

}

Currency Conversion

The convert method allows us to convert an amount from one currency to another. It constructs the necessary query parameters, including the source currency, target currency, and the amount to be converted. We then utilize the apiRequest method to perform the conversion.

import com.google.gson.JsonElement;
import java.io.IOException;

import java.net.URISyntaxException;

public class Main {

    public static void main(final String[] args) {

        try {

            // Be sure to provide your own API access key, 
            // note I used the Free Subscription Plan for this tutorial
            CurrencyConverter converter = new CurrencyConverter("5edf6c440cdaa42336d949*****");

            // Basic usage of the convert method
            JsonElement convert  = converter.convert("USD", "ZMW", "2");

            double result = convert.getAsJsonObject()
                    .getAsJsonPrimitive("result")
                    .getAsDouble();

            // Prints the conversion result
            System.out.println(result);

        } catch (URISyntaxException | IOException exception) {

            System.out.println(exception.getMessage());

        }

    }

}

Historical Exchange Rates

The historical method retrieves historical exchange rates for a specific date. It appends the date as a query parameter to the API endpoint and sends the request using the apiRequest method.

import com.google.gson.JsonElement;
import org.apache.hc.core5.http.message.BasicNameValuePair;

import java.io.IOException;

import java.net.URISyntaxException;

public class Main {

    public static void main(final String[] args) {

        try {

            // Be sure to provide your own API access key, 
            // note I used the Free Subscription Plan for this tutorial
            CurrencyConverter converter = new CurrencyConverter("5edf6c440cdaa42336d949*****");

            // Basic usage of the historical method
            JsonElement historicalRates  = converter.historical(
                    "2022-06-09",
                    new BasicNameValuePair("base", "USD")
            );

            // Prints the historical exchange rates for the date 2022-06-09
            System.out.println(historicalRates.getAsJsonObject());

        } catch (URISyntaxException | IOException exception) {

            System.out.println(exception.getMessage());

        }

    }

}

Exchange Rates for a Range of Dates

The timeframe method retrieves exchange rates for a range of dates. It takes the start date and end date as parameters, constructs the query parameters accordingly, and utilizes the apiRequest method to fetch the data.

import com.google.gson.JsonElement;
import org.apache.hc.core5.http.message.BasicNameValuePair;

import java.io.IOException;

import java.net.URISyntaxException;

public class Main {

    public static void main(final String[] args) {

        try {

            // Be sure to provide your own API access key, 
            // note I used the Free Subscription Plan for this tutorial
            CurrencyConverter converter = new CurrencyConverter("5edf6c440cdaa42336d949*****");

            // Basic usage of the timeframe method
            JsonElement timeframe  = converter.timeframe(
                    "2022-06-09", "2023-06-09",
                    new BasicNameValuePair("base", "USD")
            );

            // Prints the exchange rates for the dates  2022-06-09 and 2023-06-09
            System.out.println(timeframe.getAsJsonObject());

        } catch (URISyntaxException | IOException exception) {

            System.out.println(exception.getMessage());

        }

    }

}

Currency Change Parameters

The change method retrieves any currency’s change parameters (margin, percentage). Similar to the previous method, it constructs the necessary parameters and sends the HTTP request to the API.

import com.google.gson.JsonElement;

import java.io.IOException;

import java.net.URISyntaxException;

public class Main {

    public static void main(final String[] args) {

        try {

            // Be sure to provide your own API access key, 
            // note I used the Free Subscription Plan for this tutorial
            CurrencyConverter converter = new CurrencyConverter("5edf6c440cdaa42336d949*****");

            // Basic usage of the change method
            JsonElement changeParameters  = converter.change("USD,EUR");

            // Prints the change parameters for currencies, USD and EUR
            System.out.println(changeParameters.getAsJsonObject());

        } catch (URISyntaxException | IOException exception) {

            System.out.println(exception.getMessage());

        }

    }

}

Retrieving Supported Currencies

The list method retrievs all supported currencies by the API. It simply sends a request to the “/list” endpoint using the apiRequest method.

import com.google.gson.JsonElement;

import java.io.IOException;

import java.net.URISyntaxException;

public class Main {

    public static void main(final String[] args) {

        try {

            // Be sure to provide your own API access key, 
            // note I used the Free Subscription Plan for this tutorial
            CurrencyConverter converter = new CurrencyConverter("5edf6c440cdaa42336d949*****");

            // Basic usage of the list method
            JsonElement currencies  = converter.list();

            // Prints all supported currencies by the API
            System.out.println(currencies.getAsJsonObject());

        } catch (URISyntaxException | IOException exception) {

            System.out.println(exception.getMessage());

        }

    }

}

Conclusion

In this blog post, we explored how to build a currency converter in Java using the ExchangeRate-API. We leveraged the Apache HttpClient library for making HTTP requests and the Gson library for handling JSON responses. By following the code snippets and explanations provided, you can create a robust currency converter application that retrieves real-time exchange rates, performs currency conversions, and retrieves historical and change parameter data. Feel free to customize and enhance the code to fit your specific requirements and build upon this foundation to create more advanced currency-related applications.

Remember to handle exceptions appropriately, perform input validation, and consider implementing error handling mechanisms to ensure a robust and reliable currency converter application.

That was all I had to share with you guys. If you found this code informative and would love to see more, don’t forget to subscribe to our newsletter! 😊

Leave a Reply