我的枚举:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Currency {
USD("USD", "United States Dollar"),
EUR("EUR", "Euro"),
BGP("BGP", "British Pound"),
AUD("AUD", "Australian Dollar"),
CAD("CAD", "Canadian Dollar");
private final String shortName;
private final String fullName;
private Map<Enum, Double> rates;
Currency(String shortName, String fullName) {
this.shortName = shortName;
this.fullName = fullName;
this.rates = new HashMap<>();
}
public String getShortName() {
return shortName;
}
public String getFullName() {
return fullName;
}
public Map<Enum, Double> getRates() {
return rates;
}
}
我从另一个rest api得到的邮递员响应:
{
"shortName": "EUR",
"fullName": "Euro",
"rates": {
"AUD": 1.62,
"CAD": 1.47,
"USD": 1.11,
"BGP": 0.86,
"EUR": 1.0
}
}
标题几乎总结了我所需要的。关于如何在我的代码中序列化邮递员响应的任何想法,因此,我得到的枚举包含所有属性,包括“费率”图?
谢谢。
答案 0 :(得分:2)
您需要创建一个带有static
批注的com.fasterxml.jackson.annotation.JsonCreator
工厂方法。如果整个JSON Object
代表enum
,Jackson
会自动将其转换为Map
,因此此方法应具有如下签名:
@JsonCreator
public static Currency from(Map<String, Object> value)
以下展示柜提供了完整的实施方式:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./src/main/resources/test.json");
ObjectMapper mapper = new ObjectMapper();
Currency currency = mapper.readValue(jsonFile, Currency.class);
System.out.println(currency + " => " + currency.getRates());
}
}
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
enum Currency {
USD("USD", "United States Dollar"),
EUR("EUR", "Euro"),
BGP("BGP", "British Pound"),
AUD("AUD", "Australian Dollar"),
CAD("CAD", "Canadian Dollar");
private final String shortName;
private final String fullName;
private Map<Enum, Double> rates;
Currency(String shortName, String fullName) {
this.shortName = shortName;
this.fullName = fullName;
this.rates = Collections.emptyMap();
}
public String getShortName() {
return shortName;
}
public String getFullName() {
return fullName;
}
public Map<Enum, Double> getRates() {
return rates;
}
public static Currency fromShortName(String value) {
for (Currency currency : values()) {
if (currency.getShortName().equals(value)) {
return currency;
}
}
throw new IllegalArgumentException(value + " is not found!");
}
@JsonCreator
public static Currency from(Map<String, Object> value) {
String shortName = value.getOrDefault("shortName", "").toString();
Currency currency = fromShortName(shortName);
Map<String, Double> rates = (Map<String, Double>) value.getOrDefault("rates", Collections.emptyMap());
Map<Enum, Double> newRates = new HashMap<>(9);
rates.forEach((k, v) -> {
newRates.put(Currency.fromShortName(k), v);
});
currency.rates = Collections.unmodifiableMap(newRates);
return currency;
}
}
上面的代码显示:
EUR => {EUR=1.0, AUD=1.62, CAD=1.47, USD=1.11, BGP=0.86}
enum
应该是Immutable object,将费率Map
保留在内部并不是一个好主意。您绝对应该尝试将其从enum
中删除。在多线程环境中,您需要保证在读取过程中不会更改此Map
。因此,在实现中,我不会更改已使用的Map
,而是每次都创建一个新的。