Real-Time Currency Converter with Java + OpenExchangeRates API
Building a real-time currency converter is a practical Java project that illustrates how to consume third-party APIs, parse JSON data, and perform basic computations with real-world implications. In this blog post, we’ll walk through the development of a real-time currency converter using Java and the OpenExchangeRates API. You’ll learn how to make HTTP requests using HttpClient, handle JSON responses, implement conversion logic, and optimize the tool for extensibility and robustness.
Prerequisites: Java 11+ (for HttpClient), Maven or your preferred build tool, and a free OpenExchangeRates API key.
1. Setting Up the Project
We’ll start by setting up a Maven project with dependencies for JSON parsing using Jackson.
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
</dependencies>
Create a new class CurrencyConverter where we’ll implement our logic.
2. Making HTTP Requests with Java 11 HttpClient
Java 11 introduced the new HttpClient API, which simplifies making HTTP requests. We’ll use it to fetch exchange rates.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://openexchangerates.org/api/latest.json?app_id=YOUR_APP_ID"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
String json = response.body();
Replace YOUR_APP_ID with your actual API key. This request returns the latest exchange rates indexed by currency code with USD as the base.
3. Parsing JSON Using Jackson
Use Jackson’s ObjectMapper to parse the JSON response. First, define a POJO to map the JSON structure:
class ExchangeRates {
public String disclaimer;
public String license;
public long timestamp;
public String base;
public Map<String, Double> rates;
}
Deserialize the response with:
ObjectMapper mapper = new ObjectMapper();
ExchangeRates rates = mapper.readValue(json, ExchangeRates.class);
Now you have access to exchange rates via rates.rates.get("EUR"), for example.
4. Implementing Conversion Logic
Now that you’ve got the exchange rates, write a method to convert between any two currencies:
public static double convert(String from, String to, double amount, ExchangeRates data) {
double fromRate = data.rates.get(from);
double toRate = data.rates.get(to);
return (amount / fromRate) * toRate;
}
This method supports conversion between any currencies supported by the API. Note: since the API uses USD as the base, we normalize the amount via USD first, then apply the target rate.
5. Creating a Simple Interactive Console Application
Let’s build a basic CLI application to test our converter:
public class CurrencyConverterApp {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter amount:");
double amount = scanner.nextDouble();
System.out.println("From currency (e.g. EUR):");
String from = scanner.next().toUpperCase();
System.out.println("To currency (e.g. USD):");
String to = scanner.next().toUpperCase();
ExchangeRates rates = fetchExchangeRates();
double result = convert(from, to, amount, rates);
System.out.printf("\n%.2f %s = %.2f %s\n", amount, from, result, to);
}
}
Helper Method:
private static ExchangeRates fetchExchangeRates() throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://openexchangerates.org/api/latest.json?app_id=YOUR_APP_ID"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(response.body(), ExchangeRates.class);
}
6. Optimization and Error Handling
Production-ready applications should include robust error handling. Handle missing currency codes, connection issues, and rate limits.
if (!data.rates.containsKey(from) || !data.rates.containsKey(to)) {
throw new IllegalArgumentException("Unsupported currency code");
}
To improve performance, cache the API results and refresh them only after a defined interval. You could use a scheduled executor to refresh hourly, for example.
7. Final Thoughts and Extensions
This converter is a solid base for:
- Android apps (using Retrofit for networking)
- Web integration (Spring Boot or REST APIs)
- Desktop apps (JavaFX)
Also consider implementing:
- Historical rates lookup using the API’s
/historicalendpoint - Graphical UI using JavaFX
- Persistent storage for caching
By using standard Java features like HttpClient and Jackson, and real-world services like OpenExchangeRates, you’ve gained a practical example of modern API integration in Java. Happy coding!
Useful links:


