簡體   English   中英

轉換地圖 <String, String> 到POJO列表-java.lang.IllegalStateException:應該為BEGIN_ARRAY,但為STRING

[英]Convert Map<String, String> to List of POJO - java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING

目前,我計划將以下Map<String, String>轉換為POJO List

Map<String, String> m = new HashMap<>();
m.put("stock_price_alerts", "[{\"code\":\"KO\",\"rise_above\":7.0,\"size\":1000.89,\"price\":10,\"time\":1519625135173,\"fall_below\":null},{\"code\":\"BRK-B\",\"rise_above\":180,\"size\":100,\"price\":190,\"time\":1519160399911,\"fall_below\":null}]");
System.out.println(m);

當我們在控制台上打印出Map時,它看起來像

{stock_price_alerts=[{"code":"KO","rise_above":7.0,"size":1000.89,"price":10,"time":1519625135173,"fall_below":null},{"code":"BRK-B","rise_above":180,"size":100,"price":190,"time":1519160399911,"fall_below":null}]}

我准備2個POJO課程。

StockPriceAlert.java

package sandbox;

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class StockPriceAlert {

    @SerializedName("code")
    @Expose
    public String code;
    @SerializedName("fall_below")
    @Expose
    public Object fallBelow;
    @SerializedName("rise_above")
    @Expose
    public long riseAbove;
    @SerializedName("price")
    @Expose
    public long price;
    @SerializedName("time")
    @Expose
    public long time;
    @SerializedName("size")
    @Expose
    public long size;

    /**
    * No args constructor for use in serialization
    * 
    */
    public StockPriceAlert() {
    }

    /**
    * 
    * @param fallBelow
    * @param time
    * @param price
    * @param riseAbove
    * @param code
    * @param size
    */
    public StockPriceAlert(String code, Object fallBelow, long riseAbove, long price, long time, long size) {
        super();
        this.code = code;
        this.fallBelow = fallBelow;
        this.riseAbove = riseAbove;
        this.price = price;
        this.time = time;
        this.size = size;
    }

}

StockPriceAlertResponse.java

package sandbox;

import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class StockPriceAlertResponse {

    @SerializedName("stock_price_alerts")
    @Expose
    private List<StockPriceAlert> stockPriceAlerts = null;

    /**
     * No args constructor for use in serialization
     *
     */
    public StockPriceAlertResponse() {
    }

    /**
     *
     * @param stockPriceAlerts
     */
    public StockPriceAlertResponse(List<StockPriceAlert> stockPriceAlerts) {
        super();
        this.stockPriceAlerts = stockPriceAlerts;
    }

    public List<StockPriceAlert> getStockPriceAlerts() {
        return stockPriceAlerts;
    }

    public void setStockPriceAlerts(List<StockPriceAlert> stockPriceAlerts) {
        this.stockPriceAlerts = stockPriceAlerts;
    }

}

我編寫了以下代碼來執行轉換。

package sandbox;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author yccheok
 */
public class Main {  
    public static void main(String[] args) {
        Map<String, String> m = new HashMap<>();
        m.put("stock_price_alerts", "[{\"code\":\"KO\",\"rise_above\":7.0,\"size\":1000.89,\"price\":10,\"time\":1519625135173,\"fall_below\":null},{\"code\":\"BRK-B\",\"rise_above\":180,\"size\":100,\"price\":190,\"time\":1519160399911,\"fall_below\":null}]");

        System.out.println(m);

        final Gson gson = new GsonBuilder().create();

        JsonElement jsonElement = gson.toJsonTree(m);
        StockPriceAlertResponse stockPriceAlertResponse = gson.fromJson(jsonElement, StockPriceAlertResponse.class);
        List<StockPriceAlert> stockPriceAlerts = stockPriceAlertResponse.getStockPriceAlerts();
    }
}

但是,我得到以下異常

線程“主”中的異常com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:預期為BEGIN_ARRAY,但為STRING

知道我該如何解決嗎?

注意, Map<String, String> m是從第三方庫輸出的。 因此,該輸入超出了我的控制范圍。

簡單地做:

StockPriceAlertResponse res = gson.fromJson(""+m, StockPriceAlertResponse.class);

調用m.toString() ,它會生成如下內容:

{ stock_price_alerts= ...

但是Gson似乎可以處理=甚至應該:

注意 :您需要更改

public long size;

至:

public float size;

由於以下值:

"size": 1000.89

你的問題是,你轉換的東西,已經是JSONJSON通過調用再次toJsonTree 然后,當您對結果調用fromJson時,它將把它轉換回原來的結果: Map<String, String>

您必須直接在地圖中的值上調用fromJson 由於無論出於何種原因,您擁有的值都是一個數組(由[]包圍),因此必須首先將fromJsonJsonArray.class fromJson使用,然后將fromJson與結果數組中的第一個元素一起使用StockPriceAlert.class

    for (String value : m.values())
    {
        StockPriceAlert stockPriceAlert = gson.fromJson(gson.fromJson(value, JsonArray.class).get(0), StockPriceAlert.class);
    }

問題在於原始地圖的值將保留為String。

    String mJsonString = m.entrySet().stream()
            .map(e -> String.format("\"%s\":%s", e.getKey(), e.getValue()))
            .collect(Collectors.joining(",", "{", "}"));

    System.out.println(mJsonString);

    final Gson gson = new GsonBuilder().create();
    StockPriceAlertResponse stockPriceAlertResponse = gson.fromJson(mJsonString,
            StockPriceAlertResponse.class);
    List<StockPriceAlert> stockPriceAlerts = stockPriceAlertResponse.getStockPriceAlerts();

對於大小,數據中有一個錯誤:應該是整數的浮點值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM