从JSON到具有动态密钥的JAVA POJO

问题描述

我正在尝试从JSON转换为JAVA POJO。

我的JSON字符串如下所示:

{
  "api": {
    "results": 1,"fixtures": [
      {
        "fixture_id": 38480,"league_id": 95,"lineups": {
          "Lecce": {
            "coach": "F. Liverani","coach_id": 2442,"formation": "4-2-3-1","startXI": [
              {
                "team_id": 867,"player_id": 31719,"player": "M. Vigorito","number": 22,"pos": "G"
              },{
                "team_id": 867,"player_id": 31721,"player": "M. Calderoni","number": 27,"pos": "D"
              },"player_id": 31725,"player": "F. Lucioni","number": 25,"pos": "D"
              }
            ],"substitutes": [
              {
                "team_id": 867,"player_id": 31744,"player": "S. Palombi","number": 14,"pos": "F"
              },"player_id": 31740,"player": "A. Tabanelli","number": 23,"player_id": 31739,"player": "M. Scavone","number": 30,"pos": "M"
              }
            ]
          },"Spezia": {
            "coach": "P. Marino","coach_id": 2899,"startXI": [
              {
                "team_id": 515,"player_id": 30820,"player": "E. Lamanna","number": 1,{
                "team_id": 515,"player_id": 30829,"player": "C. Terzi","number": 19,"player_id": 30824,"player": "E. Capradossi","number": 13,"player_id": 30837,"player": "L. Mora","number": 6,"pos": "M"
              }
            ],"substitutes": [
              {
                "team_id": 515,"player_id": 30848,"player": "D. Okereke","number": 21,"player_id": 30832,"player": "M. Crimi","number": 15,"pos": "M"
              },"player_id": 30842,"player": "S. Bidaoui","number": 26,"pos": "D"
              }
            ]
          }
        }
      }
    ]
  }
}

我的问题是,“ Team”名称是动态的,并且对于我收到的每个匹配夹具JSON字符串都会更改。

我已经使用http://www.jsonschema2pojo.org/来准备文件了,但是看起来像下面这样:

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.codehaus.jackson.annotate.JsonAnyGetter;
import org.codehaus.jackson.annotate.JsonAnySetter;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.annotate.JsonPropertyOrder;
import org.codehaus.jackson.map.annotate.JsonSerialize;

@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
@JsonPropertyOrder({
    "Lecce","Spezia"
})
public class Lineups implements Serializable
{

    @JsonProperty("Lecce")
    private Lecce lecce;
    @JsonProperty("Spezia")
    private Spezia spezia;
    @JsonIgnore
    private Map<String,Object> additionalProperties = new HashMap<String,Object>();
    private final static long serialVersionUID = -2766671198131939159L;

    /**
     * No args constructor for use in serialization
     * 
     */
    public Lineups() {
    }

    /**
     * 
     * @param lecce
     * @param spezia
     */
    public Lineups(Lecce lecce,Spezia spezia) {
        super();
        this.lecce = lecce;
        this.spezia = spezia;
    }

    @JsonProperty("Lecce")
    public Lecce getLecce() {
        return lecce;
    }

    @JsonProperty("Lecce")
    public void setLecce(Lecce lecce) {
        this.lecce = lecce;
    }

    @JsonProperty("Spezia")
    public Spezia getSpezia() {
        return spezia;
    }

    @JsonProperty("Spezia")
    public void setSpezia(Spezia spezia) {
        this.spezia = spezia;
    }

    @JsonAnyGetter
    public Map<String,Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name,Object value) {
        this.additionalProperties.put(name,value);
    }

}

只要是莱切和斯佩齐亚,它就可以正常工作。如果是其他团队,我将不会获得名称和其他信息。

当我自己进行映射时,我已经成功地以另一种方式解决了这个问题。 然后我像这样解决了它:

public static class Lineups {
        private Map<String,Team> team = new LinkedHashMap<>();
        
        public Map<String,Team> getTeam() {
        return team;
        }

        public void setTeam(Map<String,Team> team) {
        this.team = team;
        }

        @JsonAnySetter
        public void setTeam(String key,Team value) {
        this.team.put(key,value);
        }
             
        public Lineups() {
            
        }
    }

但是我想组织它并使用注释,因为我在较早的设置中收到的JSON文件还有其他问题。 我尝试在新设置中使用与Map team = new LinkedHashMap ()类似的东西,但是我无法使其正常工作。

有没有人可以帮助我解决该问题并使它与我从http://www.jsonschema2pojo.org/获得的文件一起使用。

解决方法

从顶部讲:

第一部分是一个对象,其字段名为api

{
    "api": {
class Root {
    @JsonProperty("api") private API api;
}

下一部分是一个对象,该对象具有两个名为resultsfixtures的字段,其中fixtures是数组或List,我们通常更喜欢使用{{1} }:

List
        "results": 1,"fixtures": [

下一部分是一个具有三个字段的对象,分别名为class API { @JsonProperty("results") private int results; @JsonProperty("fixtures") private List<Fixture> fixtures; // array } fixture_idleague_id,其中lineupsassociative array,在Java中是lineups

Map<String,?>
            {
                "fixture_id": 38480,"league_id": 95,"lineups": {
                    "Lecce": {

其余的很简单:

class Fixture {
    @JsonProperty("fixture_id") private int fixtureId;
    @JsonProperty("league_id")  private int leagueId;
    @JsonProperty("lineups")    private Map<String,Lineup> lineups; // associative array
}
                        "coach": "F. Liverani","coach_id": 2442,"formation": "4-2-3-1","startXI": [
                            ...
                        ],"substitutes": [
                            ...
                        ]
class Lineup {
    @JsonProperty("coach")       private String coach;
    @JsonProperty("coach_id")    private int coachId;
    @JsonProperty("formation")   private String formation;
    @JsonProperty("startXI")     private List<Player> startXI;
    @JsonProperty("substitutes") private List<Player> substitutes;
}
                            {
                                "team_id": 867,"player_id": 31719,"player": "M. Vigorito","number": 22,"pos": "G"
                            },
,

我通常会真正进入代码注释(代码文档),但是使用诸如 JSON解析之类的代码时,代码行是如此自成一体不言而喻,这似乎没有必要。我正在练习使用 JSON库 javax.json ...

我不使用Java的组件注释(以前称为 Java Beans ),因此按常规方式编写constructorsgetters是我习惯了。

这是我的版本...比其他版本长,但是易读性和添加/删除方法非常简单。

import java.io.*;
import javax.json.*;
import java.util.*;

public class S
{
    public static class Player
    {
        public final String name,position;
        public final int playerId,teamId,number;
        public final boolean starting;

        public Player(String name,String position,int playerId,int teamId,int number,boolean starting)
        { 
            this.name=name; this.position=position;
            this.playerId=playerId; this.teamId=teamId; this.number=number;
            this.starting=starting;
        }

        public String toString()
        {
            return
                "Name:      " + name      + '\n' +
                "Position:  " + position  + '\n' +
                "Number:    " + number    + '\n' +
                "Starting:  " + (starting ? "Starting Lineup" : "Substitute") + '\n';
        }
    }

    public static class Team extends Vector<Player>
    {
        public final String teamName,coachName,formation;
        public final int coachId;

        public Team(String teamName,String coachName,int coachId,String formation)
        {
            this.teamName=teamName; this.coachName=coachName; this.coachId=coachId;
            this.formation=formation;
        }

        public Player findByName(String name)
        {
            for (Player player : this) if (player.name.equalsIgnoreCase(name)) return player;
            return null;
        }

        public Player findByNumber(int number)
        {
            for (Player player : this) if (player.number == number) return player;
            return null;
        }

        public Player findByPosition(String position)
        {
            for (Player player : this) if (player.position.equalsIgnoreCase(position)) return player;
            return null;
        }

        public String toString()
        {
            StringBuffer sb = new StringBuffer();
            sb.append(
                "Team Name:    " + teamName + '\n' +
                "Coach Name:   " + coachName + '\n' +
                "Formation:    " + formation + "\n\n"
            );
            for (Player player : this) sb.append(player.toString() + "\n");
            return sb.toString();
        }
    }

    public static void main(String[] argv) throws IOException
    {
        Reader r = new FileReader("teams.json");
        JsonObject teamsList = Json
            .createReader(r)
            .readObject()
            .getJsonObject("api")
            .getJsonArray("fixtures")
            .getJsonObject(0)
            .getJsonObject("lineups");
        
        Vector<Team> teams = new Vector<>();

        for (String teamName : teamsList.keySet())
        {
            JsonObject      teamObj         = teamsList.getJsonObject(teamName);
            String          coachName       = teamObj.getString("coach");
            int             coachId         = teamObj.getInt("coach_id");
            String          formation       = teamObj.getString("formation");
            JsonArray       startingLineup  = teamObj.getJsonArray("startXI");
            JsonArray       substitutes     = teamObj.getJsonArray("substitutes");
            List<JsonArray> lineups         = new Vector<>();
            Team            team            = new Team(teamName,coachId,formation);
            int             count           = 0;

            teams.add(team);
            lineups.add(startingLineup);
            lineups.add(substitutes);

            for (JsonArray lineup : lineups)
            {
                boolean starting = (count++ == 0);
                for (JsonObject playerObj : lineup.getValuesAs(JsonObject.class))
                {
                    int     teamId          = playerObj.getInt("team_id");
                    int     playerId        = playerObj.getInt("player_id");
                    String  name            = playerObj.getString("player");
                    int     number          = playerObj.getInt("number");
                    String  position        = playerObj.getString("pos");

                    Player player = new Player(name,position,playerId,number,starting);
                    team.add(player);
                }
            }
        }

        for (Team team : teams) System.out.println(team.toString() + "\n");
    }
}

此代码将产生以下输出:

Team Name:    Lecce
Coach Name:   F. Liverani
Formation:    4-2-3-1

Name:      M. Vigorito
Position:  G
Number:    22
Starting:  Starting Lineup

Name:      M. Calderoni
Position:  D
Number:    27
Starting:  Starting Lineup

Name:      F. Lucioni
Position:  D
Number:    25
Starting:  Starting Lineup

Name:      S. Palombi
Position:  F
Number:    14
Starting:  Substitute

Name:      A. Tabanelli
Position:  D
Number:    23
Starting:  Substitute

Name:      M. Scavone
Position:  M
Number:    30
Starting:  Substitute


Team Name:    Spezia
Coach Name:   P. Marino
Formation:    4-2-3-1

Name:      E. Lamanna
Position:  G
Number:    1
Starting:  Starting Lineup

Name:      C. Terzi
Position:  D
Number:    19
Starting:  Starting Lineup

Name:      E. Capradossi
Position:  D
Number:    13
Starting:  Starting Lineup

Name:      L. Mora
Position:  M
Number:    6
Starting:  Starting Lineup

Name:      D. Okereke
Position:  G
Number:    21
Starting:  Substitute

Name:      M. Crimi
Position:  M
Number:    15
Starting:  Substitute

Name:      S. Bidaoui
Position:  D
Number:    26
Starting:  Substitute