如何使用 JSON 中的动态字段将 JSON 映射到 Java POJO?
How to map JSON to Java POJO with a dynamic field in JSON?
我想创建一个映射此 JSON 对象的 Java 对象:
{
"base_currency_code": "HKD",
"base_currency_name": "Hong Kong dollar",
"amount": "150.5800",
"updated_date": "2022-03-20",
"rates": {
"GBP": {
"currency_name": "Pound sterling",
"rate": "0.0975",
"rate_for_amount": "14.6774"
}
},
"status": "success"
}
只有"GBP"
属性名称是动态字段,下次可能是其他货币符号,如"USD"
、"JPY"
等
我这样创建 Java class:
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"base_currency_code",
"base_currency_name",
"amount",
"updated_date",
"rates",
"status"
})
public class CurrencyConvertDto {
@JsonProperty("base_currency_code")
private String baseCurrencyCode;
@JsonProperty("base_currency_name")
private String baseCurrencyName;
@JsonProperty("amount")
private String amount;
@JsonProperty("updated_date")
private String updatedDate;
@JsonProperty("rates")
private Rates rates;
@JsonProperty("status")
private String status;
/*
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
*/
@JsonProperty("base_currency_code")
public String getBaseCurrencyCode() {
return baseCurrencyCode;
}
@JsonProperty("base_currency_code")
public void setBaseCurrencyCode(String baseCurrencyCode) {
this.baseCurrencyCode = baseCurrencyCode;
}
@JsonProperty("base_currency_name")
public String getBaseCurrencyName() {
return baseCurrencyName;
}
@JsonProperty("base_currency_name")
public void setBaseCurrencyName(String baseCurrencyName) {
this.baseCurrencyName = baseCurrencyName;
}
@JsonProperty("amount")
public String getAmount() {
return amount;
}
@JsonProperty("amount")
public void setAmount(String amount) {
this.amount = amount;
}
@JsonProperty("updated_date")
public String getUpdatedDate() {
return updatedDate;
}
@JsonProperty("updated_date")
public void setUpdatedDate(String updatedDate) {
this.updatedDate = updatedDate;
}
@JsonProperty("rates")
public Rates getRates() {
return rates;
}
@JsonProperty("rates")
public void setRates(Rates rates) {
this.rates = rates;
}
@JsonProperty("status")
public String getStatus() {
return status;
}
@JsonProperty("status")
public void setStatus(String status) {
this.status = status;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Rates {
private List<Map<String, String>> rateInfo = new ArrayList<Map<String, String>>();
@JsonAnySetter
public void setDynamicProperty(String name, Map<String, String> map) {
rateInfo.add(map);
}
public List<Map<String, String>> getRateInfo() {
return rateInfo;
}
public void setRateInfo(List<Map<String, String>> rateInfo) {
this.rateInfo = rateInfo;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"currency_name",
"rate",
"rate_for_amount"
})
public class RateInfo {
@JsonProperty("currency_name")
private String currencyName;
@JsonProperty("rate")
private String rate;
@JsonProperty("rate_for_amount")
private String rateForAmount;
/*
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
*/
@JsonProperty("currency_name")
public String getCurrencyName() {
return currencyName;
}
@JsonProperty("currency_name")
public void setCurrencyName(String currencyName) {
this.currencyName = currencyName;
}
@JsonProperty("rate")
public String getRate() {
return rate;
}
@JsonProperty("rate")
public void setRate(String rate) {
this.rate = rate;
}
@JsonProperty("rate_for_amount")
public String getRateForAmount() {
return rateForAmount;
}
@JsonProperty("rate_for_amount")
public void setRateForAmount(String rateForAmount) {
this.rateForAmount = rateForAmount;
}
}
但是编译的时候好像有问题。它无法将 JSON 对象映射到动态字段。有谁知道如何修理它?非常感谢。
您可以使用@JsonAnyGetter 并在地图中获取额外的动态键值对。请参考以下示例中@JsonAnyGetter 的用法,如果您还需要帮助,请告诉我。
https://www.logicbig.com/tutorials/misc/jackson/jackson-any-setter.html
可能是你想的太复杂了。
在您的 CurrencyConvertDto
class 中,而不是使用
@JsonProperty("rates")
private Rates rates;
你可以简单地使用
@JsonProperty("rates")
private Map<String, RateInfo> rates;
(当然还要相应地调整 getRates
和 setRates
方法)。
然后你就不需要 Rates
class 了。
杰克逊可以应对out-of-the-box。
它将处理任意货币代码作为地图的键,如:
{
"base_currency_code": "HKD",
"base_currency_name": "Hong Kong dollar",
"amount": "150.5800",
"updated_date": "2022-03-20",
"rates": {
"GBP": {
"currency_name": "Pound sterling",
"rate": "0.0975",
"rate_for_amount": "14.6774"
},
"EUR": {
"currency_name": "Euro",
"rate": "0.120",
"rate_for_amount": "18.07"
}
},
"status": "success"
}
顺便说一下:您不需要重复 @JsonProperty
getter 和 setter 方法的注解。放 @JsonProperty
仅在成员变量上已经足够了。
如果可以的话,
最简单的选择是使用合理的 JSON 设计。
这是一个例子:
{
"base_currency_code": "HKD",
"base_currency_name": "Hong Kong dollar",
"amount": "150.5800",
"updated_date": "2022-03-20",
"rates": {
"currentySymbol": "GBP",
"currency_name": "Pound sterling",
"rate": "0.0975",
"rate_for_amount": "14.6774"
}
},
"status": "success"
}
我想创建一个映射此 JSON 对象的 Java 对象:
{
"base_currency_code": "HKD",
"base_currency_name": "Hong Kong dollar",
"amount": "150.5800",
"updated_date": "2022-03-20",
"rates": {
"GBP": {
"currency_name": "Pound sterling",
"rate": "0.0975",
"rate_for_amount": "14.6774"
}
},
"status": "success"
}
只有"GBP"
属性名称是动态字段,下次可能是其他货币符号,如"USD"
、"JPY"
等
我这样创建 Java class:
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"base_currency_code",
"base_currency_name",
"amount",
"updated_date",
"rates",
"status"
})
public class CurrencyConvertDto {
@JsonProperty("base_currency_code")
private String baseCurrencyCode;
@JsonProperty("base_currency_name")
private String baseCurrencyName;
@JsonProperty("amount")
private String amount;
@JsonProperty("updated_date")
private String updatedDate;
@JsonProperty("rates")
private Rates rates;
@JsonProperty("status")
private String status;
/*
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
*/
@JsonProperty("base_currency_code")
public String getBaseCurrencyCode() {
return baseCurrencyCode;
}
@JsonProperty("base_currency_code")
public void setBaseCurrencyCode(String baseCurrencyCode) {
this.baseCurrencyCode = baseCurrencyCode;
}
@JsonProperty("base_currency_name")
public String getBaseCurrencyName() {
return baseCurrencyName;
}
@JsonProperty("base_currency_name")
public void setBaseCurrencyName(String baseCurrencyName) {
this.baseCurrencyName = baseCurrencyName;
}
@JsonProperty("amount")
public String getAmount() {
return amount;
}
@JsonProperty("amount")
public void setAmount(String amount) {
this.amount = amount;
}
@JsonProperty("updated_date")
public String getUpdatedDate() {
return updatedDate;
}
@JsonProperty("updated_date")
public void setUpdatedDate(String updatedDate) {
this.updatedDate = updatedDate;
}
@JsonProperty("rates")
public Rates getRates() {
return rates;
}
@JsonProperty("rates")
public void setRates(Rates rates) {
this.rates = rates;
}
@JsonProperty("status")
public String getStatus() {
return status;
}
@JsonProperty("status")
public void setStatus(String status) {
this.status = status;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Rates {
private List<Map<String, String>> rateInfo = new ArrayList<Map<String, String>>();
@JsonAnySetter
public void setDynamicProperty(String name, Map<String, String> map) {
rateInfo.add(map);
}
public List<Map<String, String>> getRateInfo() {
return rateInfo;
}
public void setRateInfo(List<Map<String, String>> rateInfo) {
this.rateInfo = rateInfo;
}
}
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({
"currency_name",
"rate",
"rate_for_amount"
})
public class RateInfo {
@JsonProperty("currency_name")
private String currencyName;
@JsonProperty("rate")
private String rate;
@JsonProperty("rate_for_amount")
private String rateForAmount;
/*
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
*/
@JsonProperty("currency_name")
public String getCurrencyName() {
return currencyName;
}
@JsonProperty("currency_name")
public void setCurrencyName(String currencyName) {
this.currencyName = currencyName;
}
@JsonProperty("rate")
public String getRate() {
return rate;
}
@JsonProperty("rate")
public void setRate(String rate) {
this.rate = rate;
}
@JsonProperty("rate_for_amount")
public String getRateForAmount() {
return rateForAmount;
}
@JsonProperty("rate_for_amount")
public void setRateForAmount(String rateForAmount) {
this.rateForAmount = rateForAmount;
}
}
但是编译的时候好像有问题。它无法将 JSON 对象映射到动态字段。有谁知道如何修理它?非常感谢。
您可以使用@JsonAnyGetter 并在地图中获取额外的动态键值对。请参考以下示例中@JsonAnyGetter 的用法,如果您还需要帮助,请告诉我。
https://www.logicbig.com/tutorials/misc/jackson/jackson-any-setter.html
可能是你想的太复杂了。
在您的 CurrencyConvertDto
class 中,而不是使用
@JsonProperty("rates")
private Rates rates;
你可以简单地使用
@JsonProperty("rates")
private Map<String, RateInfo> rates;
(当然还要相应地调整 getRates
和 setRates
方法)。
然后你就不需要 Rates
class 了。
杰克逊可以应对out-of-the-box。 它将处理任意货币代码作为地图的键,如:
{
"base_currency_code": "HKD",
"base_currency_name": "Hong Kong dollar",
"amount": "150.5800",
"updated_date": "2022-03-20",
"rates": {
"GBP": {
"currency_name": "Pound sterling",
"rate": "0.0975",
"rate_for_amount": "14.6774"
},
"EUR": {
"currency_name": "Euro",
"rate": "0.120",
"rate_for_amount": "18.07"
}
},
"status": "success"
}
顺便说一下:您不需要重复 @JsonProperty
getter 和 setter 方法的注解。放 @JsonProperty
仅在成员变量上已经足够了。
如果可以的话, 最简单的选择是使用合理的 JSON 设计。
这是一个例子:
{
"base_currency_code": "HKD",
"base_currency_name": "Hong Kong dollar",
"amount": "150.5800",
"updated_date": "2022-03-20",
"rates": {
"currentySymbol": "GBP",
"currency_name": "Pound sterling",
"rate": "0.0975",
"rate_for_amount": "14.6774"
}
},
"status": "success"
}