Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gson not parsing Class variable

Tags:

java

gson

I am using Gson and I have an object that one of its fields is a Class

class A {
…
private Class aClass;
… }

When I parse the instance to Json using default Gson object aClass comes empty.

Any idea why?

like image 640
OZG Avatar asked Dec 28 '22 11:12

OZG


2 Answers

You need custom type adapter. Here is example:

package com.sopovs.moradanen;

import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class GsonClassTest {
public static void main(String[] args) {
    Gson gson = new GsonBuilder()
            .registerTypeAdapter(Class.class, new ClassTypeAdapter())
            .setPrettyPrinting()
            .create();

    String json = gson.toJson(new Foo());
    System.out.println(json);

    Foo fromJson = gson.fromJson(json, Foo.class);
    System.out.println(fromJson.boo.getName());
}

public static class ClassTypeAdapter implements JsonSerializer<Class<?>>, JsonDeserializer<Class<?>> {

    @Override
    public JsonElement serialize(Class<?> src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(src.getName());
    }

    @Override
    public Class<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        try {
            return Class.forName(json.getAsString());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

}

public static class Foo {
    Class<?> boo = String.class;
}
}

The output of this code is:

{
  "boo": "java.lang.String"
}
java.lang.String
like image 102
Ivan Sopov Avatar answered Jan 10 '23 20:01

Ivan Sopov


When I parse the instance to Json using default Gson object aClass comes empty.

Any idea why?

In a comment in issue 340, a Gson project manager explains:

Serializing types is actually somewhat of a security problem, so we don't want to support it by default. A malicious .json file could cause your application to load classes that it wouldn't otherwise; depending on your class path loading certain classes could DoS your application.

But it's quite straightforward to write a type adapter to support this in your own app.

Of course, since serialization is not the same as deserialization, I don't understand how this is an explanation for the disabled serialization, unless the unmentioned notion is to in a sense "balance" the default behaviors of serialization with deserialization.

like image 44
Programmer Bruce Avatar answered Jan 10 '23 20:01

Programmer Bruce