【问题标题】:JSON to JAVA POJO with dynamic key带有动态密钥的 JSON 到 JAVA POJO
【发布时间】:2021-01-24 01:15:50
【问题描述】:

我正在尝试从 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"
              },
              {
                "team_id": 867,
                "player_id": 31725,
                "player": "F. Lucioni",
                "number": 25,
                "pos": "D"
              }
            ],
            "substitutes": [
              {
                "team_id": 867,
                "player_id": 31744,
                "player": "S. Palombi",
                "number": 14,
                "pos": "F"
              },
              {
                "team_id": 867,
                "player_id": 31740,
                "player": "A. Tabanelli",
                "number": 23,
                "pos": "D"
              },
              {
                "team_id": 867,
                "player_id": 31739,
                "player": "M. Scavone",
                "number": 30,
                "pos": "M"
              }
            ]
          },
          "Spezia": {
            "coach": "P. Marino",
            "coach_id": 2899,
            "formation": "4-2-3-1",
            "startXI": [
              {
                "team_id": 515,
                "player_id": 30820,
                "player": "E. Lamanna",
                "number": 1,
                "pos": "G"
              },
              {
                "team_id": 515,
                "player_id": 30829,
                "player": "C. Terzi",
                "number": 19,
                "pos": "D"
              },
              {
                "team_id": 515,
                "player_id": 30824,
                "player": "E. Capradossi",
                "number": 13,
                "pos": "D"
              },
              {
                "team_id": 515,
                "player_id": 30837,
                "player": "L. Mora",
                "number": 6,
                "pos": "M"
              }
            ],
            "substitutes": [
              {
                "team_id": 515,
                "player_id": 30848,
                "player": "D. Okereke",
                "number": 21,
                "pos": "G"
              },
              {
                "team_id": 515,
                "player_id": 30832,
                "player": "M. Crimi",
                "number": 15,
                "pos": "M"
              },
              {
                "team_id": 515,
                "player_id": 30842,
                "player": "S. Bidaoui",
                "number": 26,
                "pos": "D"
              }
            ]
          }
        }
      }
    ]
  }
}

我的问题是“团队”名称是动态的,并且会随着我收到的每个匹配夹具 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);
    }

}

只要是 Lecce 和 Spezia,它就可以正常工作。如果是其他团队,我不会得到名称和其他信息。

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

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/ 获得的文件一起工作。

【问题讨论】:

    标签: java json jsonschema2pojo


    【解决方案1】:

    从头说起:

    第一部分是一个字段名为api的对象:

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

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

            "results": 1,
            "fixtures": [
    
    class API {
        @JsonProperty("results")  private int results;
        @JsonProperty("fixtures") private List<Fixture> fixtures; // array
    }
    

    下一部分是一个包含三个字段的对象,名为fixture_idleague_idlineups,其中lineupsassociative array,在Java 中是Map&lt;String, ?&gt;

                {
                    "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"
                                },
    
    class Player {
        @JsonProperty("team_id")   private int teamId;
        @JsonProperty("player_id") private int playerId;
        @JsonProperty("player")    private String player;
        @JsonProperty("number")    private int number;
        @JsonProperty("pos")       private String pos;
    }
    

    【讨论】:

    • 感谢为我工作的安德烈亚斯。 >在看到您的答案之前,我又试了一次。 >我保留了“阵容”文件并删除了大部分文件,除了以下部分:@JsonIgnore private Map additionalProperties = new HashMap();然后我将对象更改为团队。 private Map team = new HashMap();然后我创建了一个名为 Team 的新类,其中包含与 Lecce / Spezia 文件包含的相同信息。他们使用您的解决方案或我的解决方案有什么优点或缺点吗?
    【解决方案2】:

    我通常真正进入代码 cmets(代码文档),但使用 JSON Parsing 之类的东西 - 代码行是如此自我-解释性,这似乎是不必要的。我正在练习使用 JSON 库 javax.json...

    我不使用Java的Component Annotations(以前叫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, coachName, 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, teamId, 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
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多