Самый общий способ - использовать Map<String, Object>
для представления динамической структуры полезной нагрузки JSON
. В этом случае мы всегда можем использовать метод Map#keySet()
, чтобы перечислить все свойства, и нам не нужно никаких String[]
для их сохранения. Кроме того, поиск объектов по ключу быстрее, чем использование array
или List
. Если значения нашего объекта имеют постоянную структуру, мы можем сопоставить его с 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 +
'}';
}
}
Над отпечатками кода:
Use generic Map
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}
Use Service Map
backup => Service{addresses=[127.0.0.1], healthCheckInterval=60, http='https', port=9001}
cognito => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9012}
collector => Service{addresses=[127.0.0.1], healthCheckInterval=60, http='https', port=9000}
ds => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9011}
insight-analytics => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9013}
integrations => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9014}
server => Service{addresses=[127.0.0.1], healthCheckInterval=60, http='https', port=9009}
vigile => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9443}
walt => Service{addresses=[127.0.0.1], healthCheckInterval=0, http='https', port=9010}