繁体   English   中英

响应不包含值时的 JSON 解析问题

[英]JSON parsing issue when the response does not contain values

我想使用 Java 解析 JSON 并且当我收到来自 GET 调用的值的响应时,我设法做到了这一点。 My problem comes when the response comes with no values because I get the exception: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of com.footbal.dtoStatistics.Statistics out of START_ARRAY token at

[Source: (String)"{"api":{"results":0,"statistics":[]}}"; line: 1, column: 34] (through reference chain: com.footbal.dtoStatistics.StatisticsResponse["api"]->com.footbal.dtoStatistics.Api["statistics"])

我的 JSON 没有值看起来像这样:

{
    "api": {
        "results": 0,
        "statistics": []
    }
}

我的 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;
    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;
    }
}
@JsonAutoDetect(
        fieldVisibility = JsonAutoDetect.Visibility.ANY,
        getterVisibility = JsonAutoDetect.Visibility.NONE,
        setterVisibility = JsonAutoDetect.Visibility.NONE)
public 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;

    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 StatsPercent getBallPossesion() {
        return BallPossesion;
    }

    public void setBallPossesion(StatsPercent 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 StatsPercent getPasses() {
        return Passes;
    }

    public void setPasses(StatsPercent passes) {
        Passes = passes;
    }
}
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();

为什么它适用于有值的情况,而当我没有得到任何值时它会失败? 我看不出我做错了什么。

谁能帮我解析一下?

在您的情况下,带值和不带值的 Json 是不同的。 没有值,您的 JSON 将统计信息作为列表。 而另一种情况,它不是一个列表。 您的类满足有值的第二种情况。 当没有值时, class Api应该包含List<Statistics>而不是Statistics

理想情况下,尝试对两种情况都遵循相同的结构。 如果永远不会列出统计信息,则更改:

{
    "api": {
        "results": 0,
        "statistics": []
    }
}

{
    "api": {
        "results": 0,
        "statistics": {}
    }
}

否则,如果统计信息将返回列表,请更改

{
    "api": {
        "results": 16,
        "statistics": {
            "Shots on Goal": {
                "home": "3",
                "away": "9"
            },
            "Shots off Goal": {
                "home": "5",
                "away": "3"
            },...
        }}}

{
    "api": {
        "results": 16,
        "statistics": [{
            "Shots on Goal": {
                "home": "3",
                "away": "9"
            },
            "Shots off Goal": {
                "home": "5",
                "away": "3"
            },...
        }]
      }}

此问题的解决方案非常简单:将statistics类型更改为 Object 并更新 getter/setter 和无类型映射将正常工作。

class Api {
    int results;
    Object statistics;

    public int getResults() {
        return results;
    }

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

    public Object getStatistics() {
        return statistics;
    }

    public void setStatistics(Object statistics) {
        this.statistics = statistics;
    } 
}

测试代码产生预期的 output:

String emptyStats = "{\n" + 
            "    \"api\": {\n" + 
            "        \"results\": 0,\n" + 
            "        \"statistics\": []\n" + 
            "     }\n" + 
            "}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//StatisticsResponse apiResponse = mapper.readValue(json, StatisticsResponse.class);
StatisticsResponse apiResponse = mapper.readValue(emptyStats, StatisticsResponse.class);

String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(apiResponse);
System.out.println(json);

// ----------------
{
  "api" : {
    "results" : 0,
    "statistics" : [ ]
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM