Issue
I've wrote simple currency converter which reads JSON from web service and prepare table on website with selected ratios.
Until now, my Rates class had field for each ratio, but I decided to change it to Map
. I rewrote entire class using Map
but RestTemplate
is unable to map JSON
data to my HashMap. Entire field is considered as null
.
How can I reconfigure RestTemplate
or ObjectMapper
to enable mapping JSON
to Map
?
Example JSON string that I am trying to map
Repository class I am using to read JSON
and to map it on object:
package com.github.gromo13.currencyConverter.repository;
import com.github.gromo13.currencyConverter.model.Currency;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.web.client.RestTemplate;
@Repository
public class FixerIoCurrencyRepository implements CurrencyRepository {
@Autowired
private RestTemplate restTemplate;
public void setRestTemplate(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public Currency getCurrency(String currencyCode) {
Currency currency = restTemplate.getForObject("http://api.fixer.io/latest?base={currencyCode}", Currency.class, currencyCode);
return currency;
}
}
Currency class I am mapping using JSON data: package com.github.gromo13.currencyConverter.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Currency {
private String base;
private String date;
private Rates rates;
public String getBase() {
return this.base;
}
public void setBase(String base) {
this.base = base;
}
public String getDate() {
return this.date;
}
public void setDate(String date) {
this.date = date;
}
public Rates getRates() {
return this.rates;
}
public void setRates(Rates rates) {
this.rates = rates;
}
}
Rates class (field in Currency class) with Map
that i am unable to map:
package com.github.gromo13.currencyConverter.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.HashMap;
import java.util.Map;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Rates {
private Map<String, Double> rates = new HashMap<>();
public void clear() {
rates.clear();
}
public void setRate(String currencyCode, double rate) {
rates.put(currencyCode.toUpperCase(), rate);
}
public double getRate(String currencyCode) {
return rates.get(currencyCode.toUpperCase());
}
}
My actual RestTemplate configuration: package com.github.gromo13.currencyConverter.config;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
@Configuration
public class Config {
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(0, mappingJackson2HttpMessageConverter());
return restTemplate;
}
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
return mapper;
}
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper());
return converter;
}
}
Solution
It is not going to work the way you have it now. You don't need the Rates
class, you can get rid of it entirely and use:
private Map<String, Double> rates
in the currency class.
Answered By - jny
Answer Checked By - Cary Denson (JavaFixing Admin)