簡體   English   中英

解析 JSON 異常 - 無法反序列化

[英]Parse JSON exception - cannot deserialize

I want to parse a JSON using Java and I get the following error: com.fasterxml.jackson.databind.exc.MismatchedInputException:com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.util.ArrayList<com.footbal.dtoStatistics.Statistics>在 [Source: (String)" 的 START_OBJECT 令牌中

我的 Json 看起來像這樣:

{
    "api": {
        "results": 16,
        "statistics": {
            "Shots on Goal": {
                "home": "3",
                "away": "9"
            },
            "Shots off Goal": {
                "home": "5",
                "away": "3"
            },
            "Total Shots": {
                "home": "11",
                "away": "16"
            },
            "Blocked Shots": {
                "home": "3",
                "away": "4"
            },
            "Shots insidebox": {
                "home": "4",
                "away": "14"
            },
            "Shots outsidebox": {
                "home": "7",
                "away": "2"
            },
            "Fouls": {
                "home": "10",
                "away": "13"
            },
            "Corner Kicks": {
                "home": "7",
                "away": "4"
            },
            "Offsides": {
                "home": "2",
                "away": "1"
            },
            "Ball Possession": {
                "home": "55%",
                "away": "45%"
            },
            "Yellow Cards": {
                "home": "0",
                "away": "2"
            },
            "Red Cards": {
                "home": null,
                "away": null
            },
            "Goalkeeper Saves": {
                "home": "7",
                "away": "1"
            },
            "Total passes": {
                "home": "543",
                "away": "436"
            },
            "Passes accurate": {
                "home": "449",
                "away": "355"
            },
            "Passes %": {
                "home": "83%",
                "away": "81%"
            }
        }
    }
}

我用於解析的類是:

public class StatisticsResponse {

    Api api;

    public Api getApi() {
        return api;
    }

    public void setApi(Api api) {
        this.api = api;
    }
}
public class Api {

    int results;
    List<Statistics> statistics;

    public int getResults() {
        return results;
    }

    public void setResults(int results) {
        this.results = results;
    }

    public List<Statistics> getStatistics() {
        return statistics;
    }

    public void setStatistics(List<Statistics> statistics) {
        this.statistics = statistics;
    }
}
public class Statistics {

    @JsonAlias({"Shots On Goal"})
    Stats ShotsonGoal;

    @JsonAlias({"Shots Off Goal"})
    Stats ShotsoffGoal;

    @JsonAlias({"Total Shots"})
    Stats TotalShots;

    @JsonAlias({"Blocked Shots"})
    Stats BlockedShots;

    @JsonAlias({"Shots insidebox"})
    Stats Shotsinsidebox;

    @JsonAlias({"Shots outsidebox"})
    Stats Shotsoutsidebox;
    Stats Fouls;

    @JsonAlias({"Corner Kicks"})
    Stats CornerKicks;
    Stats Offsides;

    @JsonAlias({"Ball Possession"})
    Stats BallPossesion;

    @JsonAlias({"Yellow Cards"})
    Stats YellowCards;

    @JsonAlias({"Red Cards"})
    Stats RedCards;

    @JsonAlias({"Goalkeeper Saves"})
    Stats GoalkeeperSaves;

    @JsonAlias({"Total passes"})
    Stats Totalpasses;

    @JsonAlias({"Passes accurate"})
    Stats Passesaccurate;

    @JsonAlias({"Passes %"})
    Stats Passes;

    public Stats getShotsonGoal() {
        return ShotsonGoal;
    }

    public void setShotsonGoal(Stats shotsonGoal) {
        ShotsonGoal = shotsonGoal;
    }

    public Stats getShotsoffGoal() {
        return ShotsoffGoal;
    }

    public void setShotsoffGoal(Stats shotsoffGoal) {
        ShotsoffGoal = shotsoffGoal;
    }

    public Stats getTotalShots() {
        return TotalShots;
    }

    public void setTotalShots(Stats totalShots) {
        TotalShots = totalShots;
    }

    public Stats getBlockedShots() {
        return BlockedShots;
    }

    public void setBlockedShots(Stats blockedShots) {
        BlockedShots = blockedShots;
    }

    public Stats getShotsinsidebox() {
        return Shotsinsidebox;
    }

    public void setShotsinsidebox(Stats shotsinsidebox) {
        Shotsinsidebox = shotsinsidebox;
    }

    public Stats getShotsoutsidebox() {
        return Shotsoutsidebox;
    }

    public void setShotsoutsidebox(Stats shotsoutsidebox) {
        Shotsoutsidebox = shotsoutsidebox;
    }

    public Stats getFouls() {
        return Fouls;
    }

    public void setFouls(Stats fouls) {
        Fouls = fouls;
    }

    public Stats getCornerKicks() {
        return CornerKicks;
    }

    public void setCornerKicks(Stats cornerKicks) {
        CornerKicks = cornerKicks;
    }

    public Stats getOffsides() {
        return Offsides;
    }

    public void setOffsides(Stats offsides) {
        Offsides = offsides;
    }

    public Stats getBallPossesion() {
        return BallPossesion;
    }

    public void setBallPossesion(Stats ballPossesion) {
        BallPossesion = ballPossesion;
    }

    public Stats getYellowCards() {
        return YellowCards;
    }

    public void setYellowCards(Stats yellowCards) {
        YellowCards = yellowCards;
    }

    public Stats getRedCards() {
        return RedCards;
    }

    public void setRedCards(Stats redCards) {
        RedCards = redCards;
    }

    public Stats getGoalkeeperSaves() {
        return GoalkeeperSaves;
    }

    public void setGoalkeeperSaves(Stats goalkeeperSaves) {
        GoalkeeperSaves = goalkeeperSaves;
    }

    public Stats getTotalpasses() {
        return Totalpasses;
    }

    public void setTotalpasses(Stats totalpasses) {
        Totalpasses = totalpasses;
    }

    public Stats getPassesaccurate() {
        return Passesaccurate;
    }

    public void setPassesaccurate(Stats passesaccurate) {
        Passesaccurate = passesaccurate;
    }

    public Stats getPasses() {
        return Passes;
    }

    public void setPasses(Stats passes) {
        Passes = passes;
    }
public class Stats {

    int home;
    int away;

    public int getHome() {
        return home;
    }

    public void setHome(int home) {
        this.home = home;
    }

    public int getAway() {
        return away;
    }

    public void setAway(int away) {
        this.away = away;
    }
}
try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.registerModule(new JavaTimeModule());
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            StatisticsResponse apiResponse = mapper.readValue(statisticsResponse, StatisticsResponse.class);


                statisticsList = apiResponse.getApi().getStatistics();

我認為我的問題可能來自統計數組中值的名稱包含空格的事實,並且我認為 JsonAlias 的東西存在問題,但我不知道如何聲明它。

誰能幫我解析一下?

您的 Json 沒有statistics List ,它是 JSON Object

 "statistics": { 

如果它是一個列表,它應該是,

["statistics": {

因此,如果您不想要 List,請僅使用Statistics

public class Api {
    int results;
    Statistics statistics;
}

需要對現有數據 model 應用以下更改:

  1. 如前所述,將類型List<Statistics>更改為Statistics
public class Api {

    int results;
    Statistics statistics;

    public int getResults() { return results; }
    public void setResults(int results) { this.results = results; }

    public Statistics getStatistics() { return statistics; }
    public void setStatistics(Statistics statistics) {
        this.statistics = statistics;
    }
}
  1. 將@JsonAlias 更改為@JsonProperty,
  2. 將 BallPossesion 和 Passes 的類型更改為StatsPercent
  3. 添加@JsonAutoDetect 以禁用序列化中的重復 output
@JsonAutoDetect(
        fieldVisibility = Visibility.ANY, 
        getterVisibility = Visibility.NONE, 
        setterVisibility = Visibility.NONE)
class Statistics {

    @JsonProperty ("Shots on Goal")
    Stats ShotsonGoal;

    @JsonProperty ("Shots off Goal")
    Stats ShotsoffGoal;

    @JsonProperty ("Total Shots")
    Stats TotalShots;

    @JsonProperty ("Blocked Shots")
    Stats BlockedShots;

    @JsonProperty ("Shots insidebox")
    Stats Shotsinsidebox;

    @JsonProperty ("Shots outsidebox")
    Stats Shotsoutsidebox;
    Stats Fouls;

    @JsonProperty ("Corner Kicks")
    Stats CornerKicks;
    Stats Offsides;

    @JsonProperty ("Ball Possession")
    StatsPercent BallPossesion;

    @JsonProperty ("Yellow Cards")
    Stats YellowCards;

    @JsonProperty ("Red Cards")
    Stats RedCards;

    @JsonProperty ("Goalkeeper Saves")
    Stats GoalkeeperSaves;

    @JsonProperty ("Total passes")
    Stats Totalpasses;

    @JsonProperty ("Passes accurate")
    Stats Passesaccurate;

    @JsonProperty ("Passes %")
    StatsPercent Passes;

// ... getters/setters
}
  1. 提供 class 以正確解析百分比數據

更新:您可以使用 @JsonDeserialize/@JsonSerialize 注釋並實現自定義轉換器

public class StatsPercent {

    @JsonSerialize  (converter = IntToPercentConverter.class)
    @JsonDeserialize(converter = PercentToIntConverter.class)
    int home;

    @JsonSerialize  (converter = IntToPercentConverter.class)
    @JsonDeserialize(converter = PercentToIntConverter.class)
    int away;

    public int getHome() { return home; }
    public void setHome(int home) { this.home = home; }

    public int getAway() { return away; }
    public void setAway(int away) { this.away = away; }
}

public class IntToPercentConverter extends StdConverter<Integer, String> {

    @Override
    public String convert(Integer arg) {
        return arg.toString() + "%";
    }
}

public class PercentToIntConverter extends StdConverter<String, Integer> {

    @Override
    public Integer convert(String arg) {
        if (null != arg) {
            return Integer.parseInt(arg.replace("%", ""));
        }
        return null;
    }   
}


我認為唯一的出路就是改變

    List<Statistics> statistics;

    Map<String,Stats> statistics;

刪除Statistics class 並通過Map訪問其字段

暫無
暫無

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

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