JSON 到 JAVA 带动态键的 POJO
JSON to JAVA POJO with dynamic key
我正在尝试从 JSON 转换为 JAVA POJO。
我的 JSON-string 如下所示:
{
"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);
}
}
只要是莱切和斯佩齐亚,就可以正常工作。如果是其他球队我就不会知道名字和其他信息了。
我自己做映射的时候用另一种方式成功解决了这个问题。
然后我这样解决了:
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;
}
下一部分是一个对象,有两个字段,分别是results
和fixtures
,其中fixtures
是一个数组或者是一个List
,我们一般更喜欢使用List
:
"results": 1,
"fixtures": [
class API {
@JsonProperty("results") private int results;
@JsonProperty("fixtures") private List<Fixture> fixtures; // array
}
下一部分是一个包含三个字段的对象,这些字段分别名为 fixture_id
、league_id
和 lineups
,其中 lineups
是一个 associative array,在 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; // associative array
}
剩下的还不错straight-forward:
"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;
}
我通常非常喜欢代码注释(代码文档),但是 JSON 解析 - 代码行是如此self-explanatory,似乎没有必要。我正在练习使用 JSON 库 javax.json
...
我不使用 Java 的 Component Annotations(以前称为 Java Beans) , 所以写 constructors
和 getters
是我习惯的常规方式。
这是我的版本...比其他版本长,但是可读性高并且添加/删除方法非常简单。
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
我正在尝试从 JSON 转换为 JAVA POJO。
我的 JSON-string 如下所示:
{
"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);
}
}
只要是莱切和斯佩齐亚,就可以正常工作。如果是其他球队我就不会知道名字和其他信息了。
我自己做映射的时候用另一种方式成功解决了这个问题。 然后我这样解决了:
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
有没有人可以帮助我解决这个问题并让它与我从 http://www.jsonschema2pojo.org/ 获得的文件一起工作。
自上而下:
第一部分是一个字段名为 api
:
{
"api": {
class Root {
@JsonProperty("api") private API api;
}
下一部分是一个对象,有两个字段,分别是results
和fixtures
,其中fixtures
是一个数组或者是一个List
,我们一般更喜欢使用List
:
"results": 1,
"fixtures": [
class API {
@JsonProperty("results") private int results;
@JsonProperty("fixtures") private List<Fixture> fixtures; // array
}
下一部分是一个包含三个字段的对象,这些字段分别名为 fixture_id
、league_id
和 lineups
,其中 lineups
是一个 associative array,在 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; // associative array
}
剩下的还不错straight-forward:
"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;
}
我通常非常喜欢代码注释(代码文档),但是 JSON 解析 - 代码行是如此self-explanatory,似乎没有必要。我正在练习使用 JSON 库 javax.json
...
我不使用 Java 的 Component Annotations(以前称为 Java Beans) , 所以写 constructors
和 getters
是我习惯的常规方式。
这是我的版本...比其他版本长,但是可读性高并且添加/删除方法非常简单。
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