2017-10-05 174 views
0

JSON类:gson.fromJson预期BEGIN_OBJECT但BEGIN_ARRAY

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.IllegalS引起tateException:期望BEGIN_OBJECT,但是BEGIN_ARRAY在第1行第2列路径$

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

我了解一些代码可能没有意义或看起来不合适,因为我试图排除代码故障,但显然失败。

+0

好像你从服务器接收的JSON是一个对象(数组)的列表,这意味着JSON开头“[” ,它表示一个数组而不是表示一个对象的“{”。所以无论你的服务器是否返回错误,或者你应该期望一个列表而不是一个对象。 – Piwo

回答

1

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

谢谢,我完全理解我现在的问题! –

+0

我仍然没有得到我的代码工作,我知道我现在的问题是什么,我试过你提供的代码,但它说:不兼容的类型:RankAPI不能转换为列表。 任何进一步的帮助将不胜感激 –

+0

道歉,我的答案有一个错字。我已经更新了它:'列表 r = gson.fromJson(rankJSON,List.class);' – glytching

相关问题