2017-10-05 184 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

相關問題