JSON转JAVA POJO,带有动态键

huangapple go评论65阅读模式
英文:

JSON to JAVA POJO with dynamic key

问题

import java.util.Map;
import org.codehaus.jackson.annotate.JsonAnySetter;

public class Lineups {
    private Map<String, Team> team;

    public Map<String, Team> getTeam() {
        return team;
    }

    @JsonAnySetter
    public void setTeam(String key, Team value) {
        team.put(key, value);
    }
    
    // Rest of your class
}

Please note that the key issue in your previous attempt might have been that the team map wasn't initialized before using it in the setTeam method. Make sure that the team map is properly initialized before using it.

Additionally, ensure you have the appropriate imports for the Team class and other related classes. If you're still encountering issues, please provide more context or error messages for further assistance.

英文:

I am trying to convert from JSON to JAVA POJO.

My JSON-string looks like the following:

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

My problem is that the "Team" names are dynamical and will change for each match fixture JSON String I receive.

I have used http://www.jsonschema2pojo.org/ to get ready files but then it looks like the following:

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({
    &quot;Lecce&quot;,
    &quot;Spezia&quot;
})
public class Lineups implements Serializable
{

    @JsonProperty(&quot;Lecce&quot;)
    private Lecce lecce;
    @JsonProperty(&quot;Spezia&quot;)
    private Spezia spezia;
    @JsonIgnore
    private Map&lt;String, Object&gt; additionalProperties = new HashMap&lt;String, Object&gt;();
    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(&quot;Lecce&quot;)
    public Lecce getLecce() {
        return lecce;
    }

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

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

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

    @JsonAnyGetter
    public Map&lt;String, Object&gt; getAdditionalProperties() {
        return this.additionalProperties;
    }

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

}

This works fine as long as it is Lecce and Spezia. If it is other teams I will not get the names and the other information.

I have succeded to fix this in another way when I made the mapping myself.
Then I solved it like this:

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

		public void setTeam(Map&lt;String, Team&gt; team) {
		this.team = team;
		}

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

But I wanted to organize it and use anotations since I got other problems with the JSON files I recieved in my earlier setup.
I have tried to use something similar with Map<String, Team> team = new LinkedHashMap<>() in my new setup but I can´t get it to work.

Are there anybody that can assist me in how to solve this and get it to work with the files I get from http://www.jsonschema2pojo.org/.

答案1

得分: 2

首先是一个带有名为 `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 的对象,其中 lineups 是一个关联数组,在Java中是一个 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; // 关联数组
}

其余部分相对简单:

                        "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;
}

<details>
<summary>英文:</summary>

Talking it from the top:

First part is an object with field named `api`:

```lang-json
{
    &quot;api&quot;: {
class Root {
    @JsonProperty(&quot;api&quot;) private API api;
}

Next part is an object with two fields named results and fixtures, where fixtures is an array or a List, and we generally prefer using List:

        &quot;results&quot;: 1,
        &quot;fixtures&quot;: [
class API {
    @JsonProperty(&quot;results&quot;)  private int results;
    @JsonProperty(&quot;fixtures&quot;) private List&lt;Fixture&gt; fixtures; // array
}

Next part is an object with three fields named fixture_id, league_id, and lineups, where lineups is an associative array, which in Java is a Map&lt;String, ?&gt;:

            {
                &quot;fixture_id&quot;: 38480,
                &quot;league_id&quot;: 95,
                &quot;lineups&quot;: {
                    &quot;Lecce&quot;: {
class Fixture {
    @JsonProperty(&quot;fixture_id&quot;) private int fixtureId;
    @JsonProperty(&quot;league_id&quot;)  private int leagueId;
    @JsonProperty(&quot;lineups&quot;)    private Map&lt;String, Lineup&gt; lineups; // associative array
}

The rest is pretty straight-forward:

                        &quot;coach&quot;: &quot;F. Liverani&quot;,
                        &quot;coach_id&quot;: 2442,
                        &quot;formation&quot;: &quot;4-2-3-1&quot;,
                        &quot;startXI&quot;: [
                            ...
                        ],
                        &quot;substitutes&quot;: [
                            ...
                        ]
class Lineup {
    @JsonProperty(&quot;coach&quot;)       private String coach;
    @JsonProperty(&quot;coach_id&quot;)    private int coachId;
    @JsonProperty(&quot;formation&quot;)   private String formation;
    @JsonProperty(&quot;startXI&quot;)     private List&lt;Player&gt; startXI;
    @JsonProperty(&quot;substitutes&quot;) private List&lt;Player&gt; substitutes;
}
                            {
                                &quot;team_id&quot;: 867,
                                &quot;player_id&quot;: 31719,
                                &quot;player&quot;: &quot;M. Vigorito&quot;,
                                &quot;number&quot;: 22,
                                &quot;pos&quot;: &quot;G&quot;
                            },
class Player {
    @JsonProperty(&quot;team_id&quot;)   private int teamId;
    @JsonProperty(&quot;player_id&quot;) private int playerId;
    @JsonProperty(&quot;player&quot;)    private String player;
    @JsonProperty(&quot;number&quot;)    private int number;
    @JsonProperty(&quot;pos&quot;)       private String pos;
}

答案2

得分: 0

我通常会对代码注释(代码文档)非常深入地进行处理,但对于诸如JSON解析之类的事情 - 代码行都是如此不言自明,以至于似乎是不必要的。我正在练习使用JSON库 javax.json...

我不使用Java的组件注解(曾被称为Java Beans),所以以常规方式编写构造函数getter是我习惯的方式。

以下是我的版本... 它比其他版本更长,但非常易读,并且非常简单地添加/删除方法。

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
英文:

I usually get really into code comments (Code Documentation), but with things like JSON Parsing - the lines of code are so self-explanatory, that it just seems unnecessary. I am practicing using the JSON Library javax.json...

I do not use Java's Component Annotations (used to be called Java Beans), so writing constructors and getters the regular way is what I'm used to.

Here is my version... It is longer than the other version, but highly readable and adding / removing methods is extremely simple.

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
&quot;Name:      &quot; + name      + &#39;\n&#39; +
&quot;Position:  &quot; + position  + &#39;\n&#39; +
&quot;Number:    &quot; + number    + &#39;\n&#39; +
&quot;Starting:  &quot; + (starting ? &quot;Starting Lineup&quot; : &quot;Substitute&quot;) + &#39;\n&#39;;
}
}
public static class Team extends Vector&lt;Player&gt;
{
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(
&quot;Team Name:    &quot; + teamName + &#39;\n&#39; +
&quot;Coach Name:   &quot; + coachName + &#39;\n&#39; +
&quot;Formation:    &quot; + formation + &quot;\n\n&quot;
);
for (Player player : this) sb.append(player.toString() + &quot;\n&quot;);
return sb.toString();
}
}
public static void main(String[] argv) throws IOException
{
Reader r = new FileReader(&quot;teams.json&quot;);
JsonObject teamsList = Json
.createReader(r)
.readObject()
.getJsonObject(&quot;api&quot;)
.getJsonArray(&quot;fixtures&quot;)
.getJsonObject(0)
.getJsonObject(&quot;lineups&quot;);
Vector&lt;Team&gt; teams = new Vector&lt;&gt;();
for (String teamName : teamsList.keySet())
{
JsonObject      teamObj         = teamsList.getJsonObject(teamName);
String          coachName       = teamObj.getString(&quot;coach&quot;);
int             coachId         = teamObj.getInt(&quot;coach_id&quot;);
String          formation       = teamObj.getString(&quot;formation&quot;);
JsonArray       startingLineup  = teamObj.getJsonArray(&quot;startXI&quot;);
JsonArray       substitutes     = teamObj.getJsonArray(&quot;substitutes&quot;);
List&lt;JsonArray&gt; lineups         = new Vector&lt;&gt;();
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(&quot;team_id&quot;);
int     playerId        = playerObj.getInt(&quot;player_id&quot;);
String  name            = playerObj.getString(&quot;player&quot;);
int     number          = playerObj.getInt(&quot;number&quot;);
String  position        = playerObj.getString(&quot;pos&quot;);
Player player = new Player(name, position, playerId, teamId, number, starting);
team.add(player);
}
}
}
for (Team team : teams) System.out.println(team.toString() + &quot;\n&quot;);
}
}

This code will produce this output:

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

huangapple
  • 本文由 发表于 2020年10月9日 07:17:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/64271871.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定