1. Introduction
In this tutorial, we'll learn how to format currencies by locale using Thymeleaf.
2. Maven Dependencies
Let's begin by importing the Spring Boot Thymeleaf dependency:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> <version>2.2.7.RELEASE</version> </dependency>
3. Project Setup
Our project will be a simple Spring web application that displays currencies based on the user's locale. Let's create our Thymeleaf template, currencies.html, in resources/templates/currencies:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Currency table</title> </head> </html>
We can also create a controller class that will handle our requests:
@Controller public class CurrenciesController { @GetMapping(value = "/currency") public String exchange( @RequestParam(value = "amount") String amount, Locale locale) { return "currencies/currencies"; } }
4. Formatting
When it comes to currencies, we need to format them based on the requester's locale.
In this case, we'll send the Accept-Language header with each request to represent our user's locale.
4.1. Currency
The Numbers class, provided by Thymeleaf, has support for formatting currencies. So, let's update our view with a call to the formatCurrency method
<p th:text="${#numbers.formatCurrency(param.amount)}"></p>
When we run our example, we'll see the currency properly formatted:
@Test public void whenCallCurrencyWithUSALocale_ThenReturnProperCurrency() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/currency") .header("Accept-Language", "en-US") .param("amount", "10032.5")) .andExpect(status().isOk()) .andExpect(content().string(containsString("$10,032.50"))); }
Since we set the Accept-Language header to the United States, the currency is formatted with a decimal point and a dollar sign.
4.2. Currency Arrays
We can also use the Numbers class to format arrays. As a result, we'll add another request parameter to our controller:
@GetMapping(value = "/currency") public String exchange( @RequestParam(value = "amount") String amount, @RequestParam(value = "amountList") List amountList, Locale locale) { return "currencies/currencies"; }
Next, we can update our view to include a call to the listFormatCurrency method:
<p th:text="${#numbers.listFormatCurrency(param.amountList)}"></p>
Now let's see what the result looks like:
@Test public void whenCallCurrencyWithRomanianLocaleWithArrays_ThenReturnLocaleCurrencies() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/currency") .header("Accept-Language", "ro-RO") .param("amountList", "10", "20", "30")) .andExpect(status().isOk()) .andExpect(content().string(containsString("10,00 RON, 20,00 RON, 30,00 RON"))); }
The result shows the currency list with the proper Romanian formatting added.
4.3. Trailing Zeros
Using Strings#replace, we can remove the trailing zeros.
<p th:text="${#strings.replace(#numbers.formatCurrency(param.amount), '.00', '')}"></p>
Now we can see the full amount without trailing double zeros:
@Test public void whenCallCurrencyWithUSALocaleWithoutDecimal_ThenReturnCurrencyWithoutTrailingZeros() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/currency") .header("Accept-Language", "en-US") .param("amount", "10032")) .andExpect(status().isOk()) .andExpect(content().string(containsString("$10,032"))); }
4.4. Decimals
Depending on the locale, decimals may be formatted differently. Therefore, if we want to replace a decimal point with a comma, we can use the formatDecimal method provided by the Numbers class:
<p th:text="${#numbers.formatDecimal(param.amount, 1, 2, 'COMMA')}"></p>
Let's see the outcome in a test:
@Test public void whenCallCurrencyWithUSALocale_ThenReturnReplacedDecimalPoint() throws Exception { mockMvc.perform(MockMvcRequestBuilders.get("/currency") .header("Accept-Language", "en-US") .param("amount", "1.5")) .andExpect(status().isOk()) .andExpect(content().string(containsString("1,5"))); }
The value will be formatted as “1,5”.
5. Conclusion
In this short tutorial, we showed how Thymeleaf can be used with Spring Web to handle currencies using the user's Locale.
As always, the code is available over on GitHub.