2

I have a UI which sends this object - com.google.api.services.compute.model.Network in JSON format as part of a HTTP request. I need to deserialize this object to the Java object. How do I do that? I wrote a simple POJO like below to mimic the behaviour.

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()); 
    }

}

And this is the output I get.

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)

I don't know if I have to register all the nested types upfront and how to do it.

1 Answer 1

3

It looks like com.google.api.services.* has it's own com.google.api.client.json.* package which should be used in this case to serialise model to JSON and deserialise JSON to model. See below example:

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());
    }
}

Above code prints:

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

And you do not need to use Gson.

Sign up to request clarification or add additional context in comments.

1 Comment

right now, this is the only way. Jackson's ObjectMapper also doesn't work even with mixins or any combination of feature disable/enable configurations.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.