Java 使用GSON库解析后如何处理json元素?
我已将以下有效负载设置到Java 使用GSON库解析后如何处理json元素?,java,parsing,gson,Java,Parsing,Gson,我已将以下有效负载设置到Gson的JsonObject: { "backup": { "addresses": [ "127.0.0.1" ], "healthcheck_interval": "60", "http": "https", "port": "9001" }, "cognit
Gson
的JsonObject
:
{
"backup": {
"addresses": [
"127.0.0.1"
],
"healthcheck_interval": "60",
"http": "https",
"port": "9001"
},
"cognito": {
"addresses": [
"127.0.0.1"
],
"http": "https",
"port": "9012"
},
"collector": {
"addresses": [
"127.0.0.1"
],
"healthcheck_interval": "60",
"http": "https",
"port": "9000"
},
"ds": {
"addresses": [
"127.0.0.1"
],
"http": "https",
"port": "9011"
},
"insight-analytics": {
"addresses": [
"127.0.0.1"
],
"http": "https",
"port": "9013"
},
"integrations": {
"addresses": [
"127.0.0.1"
],
"http": "https",
"port": "9014"
},
"server": {
"addresses": [
"127.0.0.1"
],
"healthcheck_interval": "60",
"http": "https",
"port": "9009"
},
"vigile": {
"addresses": [
"127.0.0.1"
],
"http": "https",
"port": "9443"
},
"walt": {
"addresses": [
"127.0.0.1"
],
"http": "https",
"port": "9010"
}
}
测试:
我希望能够将JSON
的所有成员存储到字符串数组中(backup
,cognito
,collector
,等等),这样我就可以使用字符串数组找到对象以获得更多值(例如healthcheck\u interval
,http
,port
,等等)。我尝试使用streams来实现这一目标,但没有成功。
我想这样做,因为将来很可能会更改字段的名称(而不是
backup
它可以更改为另一个名称)。您需要重新考虑您的问题。GSON的优点在于它能够从实际的Java对象反射地序列化和取消序列化JSON
这意味着您应该首先定义您的对象,然后让GSON做脏活,例如:
class Server
{
List<String> addresses;
int healthcheck_interval;
String http;
int port;
}
类服务器
{
列出地址;
int健康检查间隔;
字符串http;
国际港口;
}
这样你就可以
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
List<Server> servers = gson.fromJson(json,
new TypeToken<List<Server>>(){}.getType()
);
GsonBuilder=newgsonbuilder();
Gson Gson=builder.create();
List servers=gson.fromJson(json,
新的TypeToken(){}.getType()
);
你需要重新思考你的问题。GSON的优点在于它能够从实际的Java对象反射地序列化和取消序列化JSON
这意味着您应该首先定义您的对象,然后让GSON做脏活,例如:
class Server
{
List<String> addresses;
int healthcheck_interval;
String http;
int port;
}
类服务器
{
列出地址;
int健康检查间隔;
字符串http;
国际港口;
}
这样你就可以
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
List<Server> servers = gson.fromJson(json,
new TypeToken<List<Server>>(){}.getType()
);
GsonBuilder=newgsonbuilder();
Gson Gson=builder.create();
List servers=gson.fromJson(json,
新的TypeToken(){}.getType()
);
最通用的方法是使用Map
来表示JSON
负载的动态结构。在这种情况下,我们可以始终使用方法列出所有属性,而不需要任何String[]
来保留它们。此外,按键查找对象比使用数组
或列表
更快。如果我们的对象值具有常量结构,我们可以将其映射到POJO
,以便在运行时稳定地访问值。下面的代码显示了这两种情况:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder().create();
System.out.println("Use generic Map");
Type genericMapType = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> map = gson.fromJson(new FileReader(jsonFile), genericMapType);
map.forEach((k, v) -> System.out.println(k + " => " + v));
System.out.println();
System.out.println();
System.out.println("Use Service Map");
Type serviceMapType = new TypeToken<Map<String, Service>>() {
}.getType();
Map<String, Service> serviceMap = gson.fromJson(new FileReader(jsonFile), serviceMapType);
serviceMap.forEach((k, v) -> System.out.println(k + " => " + v));
}
}
class Service {
private List<String> addresses;
@SerializedName("healthcheck_interval")
private int healthCheckInterval;
private String http;
private int port;
public List<String> getAddresses() {
return addresses;
}
public void setAddresses(List<String> addresses) {
this.addresses = addresses;
}
public int getHealthCheckInterval() {
return healthCheckInterval;
}
public void setHealthCheckInterval(int healthCheckInterval) {
this.healthCheckInterval = healthCheckInterval;
}
public String getHttp() {
return http;
}
public void setHttp(String http) {
this.http = http;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
@Override
public String toString() {
return "Service{" +
"addresses=" + addresses +
", healthCheckInterval=" + healthCheckInterval +
", http='" + http + '\'' +
", port=" + port +
'}';
}
}
最通用的方法是使用
Map
来表示JSON
负载的动态结构。在这种情况下,我们可以始终使用方法列出所有属性,而不需要任何String[]
来保留它们。此外,按键查找对象比使用数组
或列表
更快。如果我们的对象值具有常量结构,我们可以将其映射到POJO
,以便在运行时稳定地访问值。下面的代码显示了这两种情况:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder().create();
System.out.println("Use generic Map");
Type genericMapType = new TypeToken<Map<String, Object>>() {
}.getType();
Map<String, Object> map = gson.fromJson(new FileReader(jsonFile), genericMapType);
map.forEach((k, v) -> System.out.println(k + " => " + v));
System.out.println();
System.out.println();
System.out.println("Use Service Map");
Type serviceMapType = new TypeToken<Map<String, Service>>() {
}.getType();
Map<String, Service> serviceMap = gson.fromJson(new FileReader(jsonFile), serviceMapType);
serviceMap.forEach((k, v) -> System.out.println(k + " => " + v));
}
}
class Service {
private List<String> addresses;
@SerializedName("healthcheck_interval")
private int healthCheckInterval;
private String http;
private int port;
public List<String> getAddresses() {
return addresses;
}
public void setAddresses(List<String> addresses) {
this.addresses = addresses;
}
public int getHealthCheckInterval() {
return healthCheckInterval;
}
public void setHealthCheckInterval(int healthCheckInterval) {
this.healthCheckInterval = healthCheckInterval;
}
public String getHttp() {
return http;
}
public void setHttp(String http) {
this.http = http;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
@Override
public String toString() {
return "Service{" +
"addresses=" + addresses +
", healthCheckInterval=" + healthCheckInterval +
", http='" + http + '\'' +
", port=" + port +
'}';
}
}
我尝试了您的方法,但出现了以下错误:com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:应为BEGIN_数组,但在第1行第2列path$处为BEGIN_对象,因为您的json文件是一个映射,而不是一个列表,您应该取消序列化为
映射
,检查此答案以查看细微差别我检查了您建议的答案,但使用此选项将丢失我的json对象根名称(“备份”、“收集器”等)-我希望能够将所有根名称保存到一个列表中,这样在json对象内搜索时,我将获得相关的根名称。您不会丢失它们,它们将成为映射中的键,这样您的Map.Entry
将保存它们。我认为在尝试更复杂的事情之前,您需要正确地了解语言和SDK。您已经说过,您建议的结果将保留根对象名称作为键和端口,http,etc将是它的值吗?我尝试了您的方法,得到了以下错误:com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:应为BEGIN_数组,但在第1行第2列路径$处为BEGIN_对象,因为您的json文件是一个映射,而不是列表,您应该取消序列化为map
,检查此答案以查看细微差别我检查了您建议的答案,但使用此选项将丢失我的json对象根名称(“备份”、“收集器”等)-我希望能够将所有根名称保存到一个列表中,这样在json对象内搜索时,我将获得相关的根名称。您不会丢失它们,它们将成为映射中的键,这样您的Map.Entry
将保存它们。在尝试更复杂的事情之前,我认为您需要正确了解语言和SDK。您已经说过,您建议的结果将保留根对象名称作为键,端口、http等将是其值?Ziober感谢您的回答,我还有一个问题:如果我想随机选择键,地图上的值项我怎么做?@tupacshakur,没问题。关于随机值,请参见Ziober谢谢你的回答,我还有一个问题:如果我想从地图中随机选择键、值项,我该怎么做?@tupacshakur,没问题。有关随机值,请参见