gson.fromJson预计BEGIN_OBJECT但是BEGIN_ARRAY

时间:2017-10-05 08:21:03

标签: java json javafx gson

json class:

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类完全相同。

我理解一些代码可能没有意义或似乎不合适,那是因为我试图对代码进行故障排除但显然失败了。

1 个答案:

答案 0 :(得分:2)

看起来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));
    }
}