java - gson.fromJson 预期为 BEGIN_OBJECT,但实际为 BEGIN_ARRAY

标签 java json javafx gson

json 类:

package json;

public class RankAPI {
    private String hotStreak;
    private String leagueName;
    private String tier;
    private String freshBlood;
    private String playerOrTeamId;
    private String leaguePoints;
    private String inactive;
    private String rank;
    private String veteran;
    private String queueType;
    private String losses;
    private String playerOrTeamName;
    private String wins;

public String getHotStreak ()
{
    return hotStreak;
}

public void setHotStreak (String hotStreak)
{
    this.hotStreak = hotStreak;
}

public String getLeagueName ()
{
    return leagueName;
}

public void setLeagueName (String leagueName)
{
    this.leagueName = leagueName;
}

public String getTier ()
{
    return tier;
}

public void setTier (String tier)
{
    this.tier = tier;
}

public String getFreshBlood ()
{
    return freshBlood;
}

public void setFreshBlood (String freshBlood)
{
    this.freshBlood = freshBlood;
}

public String getPlayerOrTeamId ()
{
    return playerOrTeamId;
}

public void setPlayerOrTeamId (String playerOrTeamId)
{
    this.playerOrTeamId = playerOrTeamId;
}

public String getLeaguePoints ()
{
    return leaguePoints;
}

public void setLeaguePoints (String leaguePoints)
{
    this.leaguePoints = leaguePoints;
}

public String getInactive ()
{
    return inactive;
}

public void setInactive (String inactive)
{
    this.inactive = inactive;
}

public String getRank ()
{
    return rank;
}

public void setRank (String rank)
{
    this.rank = rank;
}

public String getVeteran ()
{
    return veteran;
}

public void setVeteran (String veteran)
{
    this.veteran = veteran;
}

public String getQueueType ()
{
    return queueType;
}

public void setQueueType (String queueType)
{
    this.queueType = queueType;
}

public String getLosses ()
{
    return losses;
}

public void setLosses (String losses)
{
    this.losses = losses;
}

public String getPlayerOrTeamName ()
{
    return playerOrTeamName;
}

public void setPlayerOrTeamName (String playerOrTeamName)
{
    this.playerOrTeamName = playerOrTeamName;
}

public String getWins ()
{
    return wins;
}

public void setWins (String wins)
{
    this.wins = wins;
}

@Override
public String toString()
{
    return "ClassPojo [hotStreak = "+hotStreak+", leagueName = "+leagueName+", tier = "+tier+", freshBlood = "+freshBlood+", playerOrTeamId = "+playerOrTeamId+", leaguePoints = "+leaguePoints+", inactive = "+inactive+", rank = "+rank+", veteran = "+veteran+", queueType = "+queueType+", losses = "+losses+", playerOrTeamName = "+playerOrTeamName+", wins = "+wins+"]";
}
}

其他代码:

package com.rhidlor.leaguetool;

import json.SummonerAPI;
import json.RankAPI;
import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class FXMLController implements Initializable {
    public static OkHttpClient client = new OkHttpClient();
    public static Gson gson = new Gson();
    public static SummonerAPI summonerAPI;
    public static RankAPI rankAPI;
    public static String summonerJSON = null;
    public static String rankJSON = null;
    public static String username;
    public static String id;
    public String key = "RGAPI-dd11b8d0-3178-4eb1-8dfa-0d5bf6fb1b24";
    //https://na1.api.riotgames.com

@FXML private Label summonerLabel;
@FXML private Label rankLabel;
@FXML private Label winrateLabel;
@FXML private TextField usernameTextField;

@FXML
private void handleButtonAction(ActionEvent event) {
    username = usernameTextField.getText();
    try{
        summonerJSON  = getJSON("https://na1.api.riotgames.com/lol/summoner/v3/summoners/by-name/" + username + "?api_key=" + key);  
    }catch(Exception e) {
            e.printStackTrace();
    }
    summonerAPI = gson.fromJson(summonerJSON, SummonerAPI.class);
    id = summonerAPI.getId();
    System.out.println("ID: " + id);

    try{
        rankJSON = getJSON("https://na1.api.riotgames.com/lol/league/v3/positions/by-summoner/" + id + "?api_key=" + key);
        System.out.println("This worked");
    }catch(Exception e) {
        System.out.println("This failed");
        e.getCause().printStackTrace();
    }
    rankAPI = gson.fromJson(rankJSON, RankAPI.class);

    setValues(username);
}

public static String getJSON(String url) throws IOException {
    Request request = new Request.Builder()
    .url(url)
    .build();

    Response response = client.newCall(request).execute();
    return response.body().string();
}

public void setValues(String username){
    summonerLabel.setText(username + " Level: " + summonerAPI.getSummonerLevel());
    //System.out.println(rankAPI.getWins());
    //rankLabel.setText("Rank: " + rankAPI.getTier() + " " + rankAPI.getRank() + " LP: " + rankAPI.getLeaguePoints());
    //int winrate = (parseInt(rankAPI.getWins()) / (parseInt(rankAPI.getWins()) + parseInt(rankAPI.getLosses()))) * 100;
    //winrateLabel.setText("Winrate: " + winrate + "%");
}

@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO
}    

}

此行导致错误:

rankAPI = gson.fromJson(rankJSON, RankAPI.class);

错误:由以下原因引起:java.lang.IllegalStateException:预期为 BEGIN_OBJECT,但在第 1 行第 2 列路径 $ 处为 BEGIN_ARRAY

如果有人能帮助我,我将不胜感激。此代码的 SummonerAPI 部分工作完美,它的 json 类几乎与 RankAPI json 类相同。

我知道有些代码可能没有意义或看起来不合适,那是因为我试图对代码进行故障排除,但显然失败了。

最佳答案

看起来 JSON 字符串 ( rankJSON ) 是一个 JSON 文档数组,而不是单个 JSON 文档。

如果您记录该 JSON,您会发现它以 [ 开头例如

[
    {
        ...
    }
]

您正在尝试将其反序列化为单个 RankAPI ,您应该将其反序列化为 List<RankAPI> ,例如;

List<RankAPI> r = gson.fromJson(rankJSON, new TypeToken<ArrayList<RankAPI>>(){}.getType());

这是验证此行为的测试用例:

@Test
public void twoWayTransform() {
    Gson gson = new GsonBuilder().serializeNulls().create();

    List<RankAPI> incomings = Arrays.asList(new RankAPI(), new RankAPI());

    String json = gson.toJson(incomings);

    // use TypeToken to inform Gson about the type of the elements in the generic list
    List<RankAPI> fromJson = gson.fromJson(json, new TypeToken<ArrayList<RankAPI>>(){}.getType());

    assertEquals(2, fromJson.size());
    for (RankAPI incoming : incomings) {
        // this will pass if RankAPI has an equals() method
        assertTrue(fromJson.contains(incoming));
    }
}

关于java - gson.fromJson 预期为 BEGIN_OBJECT,但实际为 BEGIN_ARRAY,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46580967/

相关文章:

php - 解码 laravel 4 Input::json()

json - 在 Postgres 中查询 JSON

javascript - 在 javascript for 循环中查询多个 JSON 表

Java setOnAction 订阅抛出异常的事件

javafx - 如何禁用 JavaFX MenuBar 的助记符?

java - 在哪里可以找到所有可能的 Java 编译时错误的列表?

java - 与 "%A%B%"的 SQL LIKE 子句等效的 Java RegEx 是什么?

java - Windows 8.1。 - Java - ODBC 驱动程序 - NetBeans

java - 了解如何访问 geb.Page 上的内容对象

失去焦点后不调用 JavaFX onInputMethodTextChanged