Как мне десериализовать строку json в объект Java в App Engine

#json #google-cloud-platform #gson #google-http-client

#json #google-cloud-platform #gson #google-http-клиент

Вопрос:

У меня есть, UI который отправляет этот объект — com.google.api.services.compute.model.Network в JSON формате как часть HTTP запроса. Мне нужно десериализовать этот объект в Java объект. Как мне это сделать? Я написал простой, POJO подобный приведенному ниже, чтобы имитировать поведение.

 package com.techm.studio.client;

import java.io.IOException;

import com.google.api.services.compute.model.Network;
import com.google.api.services.compute.model.NetworkRoutingConfig;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class JSONTest {

    public static void main(String[] args) throws IOException {

        Network network = new Network();

        network.setName("k-network");
        network.setAutoCreateSubnetworks(false);
        network.setDescription("My test network on Google Cloud");
        network.setIPv4Range("10.0.0.0/16");
        network.setRoutingConfig(new NetworkRoutingConfig().setRoutingMode("REGIONAL"));

        String nwkJsonString = new GsonBuilder().setPrettyPrinting().create().toJson(network);
        System.out.println("JSON String from POJO ==>n"   nwkJsonString);

        Network netwrkOut = new Gson().fromJson(nwkJsonString, Network.class);
        System.out.println(netwrkOut.toPrettyString()); 
    }

}
  

И это результат, который я получаю.

 JSON String from POJO ==>
{
  "IPv4Range": "10.0.0.0/16",
  "autoCreateSubnetworks": false,
  "description": "My test network on Google Cloud",
  "name": "k-network",
  "routingConfig": {
    "routingMode": "REGIONAL"
  }
}
Exception in thread "main" java.lang.IllegalArgumentException: Can not set com.google.api.services.compute.model.NetworkRoutingConfig field com.google.api.services.compute.model.Network.routingConfig to com.google.gson.internal.LinkedTreeMap
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
    at java.lang.reflect.Field.set(Field.java:764)
    at com.google.api.client.util.FieldInfo.setFieldValue(FieldInfo.java:280)
    at com.google.api.client.util.FieldInfo.setValue(FieldInfo.java:241)
    at com.google.api.client.util.GenericData.put(GenericData.java:104)
    at com.google.api.client.util.GenericData.put(GenericData.java:48)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:188)
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
    at com.google.gson.Gson.fromJson(Gson.java:887)
    at com.google.gson.Gson.fromJson(Gson.java:852)
    at com.google.gson.Gson.fromJson(Gson.java:801)
    at com.google.gson.Gson.fromJson(Gson.java:773)
    at com.techm.studio.client.JSONTest.main(JSONTest.java:25)
  

Я не знаю, нужно ли мне заранее регистрировать все вложенные типы и как это сделать.

Ответ №1:

Похоже, что у него com.google.api.services.* есть собственный com.google.api.client.json.* пакет, который следует использовать в этом случае для сериализации model в JSON и десериализации JSON в model. Смотрите пример ниже:

 import com.google.api.client.json.JsonGenerator;
import com.google.api.client.json.JsonParser;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.compute.model.Network;
import com.google.api.services.compute.model.NetworkRoutingConfig;

import java.io.StringWriter;

public class GsonApp {

    public static void main(String[] args) throws Exception {
        Network network = new Network();

        network.setName("k-network");
        network.setAutoCreateSubnetworks(false);
        network.setDescription("My test network on Google Cloud");
        network.setIPv4Range("10.0.0.0/16");
        network.setRoutingConfig(new NetworkRoutingConfig().setRoutingMode("REGIONAL"));

        JacksonFactory jacksonFactory = new JacksonFactory();
        StringWriter writer = new StringWriter();
        try (JsonGenerator jsonGenerator = jacksonFactory.createJsonGenerator(writer)) {
            jsonGenerator.enablePrettyPrint();
            jsonGenerator.serialize(network);
        }

        String nwkJsonString = writer.toString();
        System.out.println("JSON String from POJO ==>n"   nwkJsonString);

        JsonParser jsonParser = jacksonFactory.createJsonParser(nwkJsonString);
        Network netwrkOut = jsonParser.parse(Network.class);
        System.out.println(netwrkOut.toPrettyString());
    }
}
  

Приведенный выше код печатает:

 JSON String from POJO ==>
{
  "IPv4Range" : "10.0.0.0/16",
  "autoCreateSubnetworks" : false,
  "description" : "My test network on Google Cloud",
  "name" : "k-network",
  "routingConfig" : {
    "routingMode" : "REGIONAL"
  }
}
{
  "IPv4Range" : "10.0.0.0/16",
  "autoCreateSubnetworks" : false,
  "description" : "My test network on Google Cloud",
  "name" : "k-network",
  "routingConfig" : {
    "routingMode" : "REGIONAL"
  }
}
  

И вам не нужно использовать Gson .

Комментарии:

1. на данный момент это единственный способ. Jackson ObjectMapper также не работает даже с миксинами или любой комбинацией конфигураций отключения / включения функций.