简体   繁体   English

如何将JSON转换为Java集合

[英]How can I convert JSON to Java collection

I'm trying to consume the following API result into a Java object. 我正在尝试将以下API结果用于Java对象。 The code can be seen below. 代码如下所示。

public Map<String, List<CurrencyData>> gsonCurrency(String answer) {

    Gson g = new Gson();
    CurrencyData currencyData = null;

    Map<String, List<CurrencyData>> object;
    try {
        object = g.fromJson(answer,
                new TypeToken<Map<String, List<CurrencyData>>>().getType());

    } catch (Exception e) {
        throw new OutputFromApiException("HistoricalFlight API output is empty ", e.toString());

    }

    return object;
public class CurrencyData {

    @SerializedName("rates")
    @Expose
    private Rates rates;

    @SerializedName("base")
    @Expose
    private String base;

    @SerializedName("date")
    @Expose
    private String date;

    // Getters & Setters
}

I get the following error. 我收到以下错误。

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 11 path $. 预期BEGIN_ARRAY但是第1行第11行路径$为BEGIN_OBJECT。

Your CurrencyData is not representative of the payload from the API endpoint you are calling. 您的CurrencyData不代表您正在呼叫的API端点的有效负载。 The quickest fix is to change Rates rate to a Map of String currency keys to BigDecimal 's. 最快的解决方法是将Rates rate更改为String of String货币键到BigDecimal的。 Don't use Double as you will get precision errors. 不要使用Double因为你会得到精度错误。

    public static class CurrencyData {
        @SerializedName("rates")
        @Expose
        private Map<String, BigDecimal> rates;
        ...
    }

You are also deserializing the wrong data structure. 您还要反序列化错误的数据结构。 You only need to deserialize an instance of CurrencyData. 您只需要反序列化CurrencyData的实例。

    public CurrencyData gsonCurrency(String answer) {
        try {
            return new Gson().fromJson(answer, CurrencyData.class);
        } catch (Exception e) {
            throw new OutputFromApiException("HistoricalFlight API output is empty ", e.toString());
        }
    }

You need to modify your CurrencyData class to look like the following for it to be able to consume your API result. 您需要将CurrencyData类修改为如下所示,以便能够使用您的API结果。

public final class CurrencyData {

    @SerializedName("rates")
    private Map<String, BigDecimal> rates = new HashMap<>();

    @SerializedName("base")
    private String base;

    @SerializedName("date")
    private String date;

    public Map<String, BigDecimal> getRates() {
        return rates;
    }

    public void setRates(Map<String, BigDecimal> rates) {
        this.rates = rates;
    }

    public String getBase() {
        return base;
    }

    public void setBase(String base) {
        this.base = base;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }
}

Now you can do the following example. 现在您可以执行以下示例。

Gson gson = new Gson();

CurrencyData data = new CurrencyData();
data.setBase("USD");
data.setDate("2019-01-01");

Map<String, BigDecimal> ratesMap = new HashMap<>();
ratesMap.put("SEK", new BigDecimal("9.1"));
ratesMap.put("DKK", new BigDecimal("8.2"));
data.setRates(ratesMap);

String json = gson.toJson(data);

System.out.println(json);

Which prints: 哪个印刷品:

{"base":"USD","date":"2019-01-01","rates":{"DKK":8.2,"SEK":9.1}}

You can also reverse the process like so. 您也可以像这样反转这个过程。

CurrencyData parsedData = gson.fromJson(json, CurrencyData.class);
// Prints only the "rates"
System.out.println(parsedData.getRates().toString());

Which prints: 哪个印刷品:

{DKK=8.2, SEK=9.1}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM