gson Android:尝试序列化...忘记注册类型适配器了吗?”

hc8w905p  于 2022-11-06  发布在  Android
关注(0)|答案(2)|浏览(162)

如何使用Gson将HashMap转换为JSON。

class ClassData {
    public String jsonString;
    public Class classType;
}
HashMap<String, ClassData> map = new HashMap<>();

void convert(){
    new Gson().toJson(map); // throws
}

我正在获取下一个异常
尝试序列化java.lang.Class:java.lang.String。忘记注册类型适配器?

envsm3lx

envsm3lx1#

我的方法适用于Gson 2.3.1与Java 1.7,不能保证它将与Android一起工作。
问题出在变量classType上,因为Gson不能处理Class类型,所以我们必须为Class创建一个TypeAdapter。

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;

public class ClassTypeAdapter extends TypeAdapter<Class<?>> {
    @Override
    public void write(JsonWriter jsonWriter, Class<?> clazz) throws IOException {
        if(clazz == null){
            jsonWriter.nullValue();
            return;
        }
        jsonWriter.value(clazz.getName());
    }

    @Override
    public Class<?> read(JsonReader jsonReader) throws IOException {
        if (jsonReader.peek() == JsonToken.NULL) {
            jsonReader.nextNull();
            return null;
        }
        Class<?> clazz = null;
        try {
            clazz = Class.forName(jsonReader.nextString());
        } catch (ClassNotFoundException exception) {
            throw new IOException(exception);
        }
        return clazz;
    }
}

要使其正常工作,您需要一个TypeAdapterFactory。

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;

public class ClassTypeAdapterFactory implements TypeAdapterFactory {
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
        if(!Class.class.isAssignableFrom(typeToken.getRawType())) {
            return null;
        }
        return (TypeAdapter<T>) new ClassTypeAdapter();
    }
}

并将TypeAdapterFactory注册到Gson构建器。

gsonBuilder.registerTypeAdapterFactory(new ClassTypeAdapterFactory());

AFAIK您必须使用TypeAdapterFactory。直接注册的TypeAdapter

gsonBuilder.registerTypeAdapter(Class.class, new ClassTypeAdapter());

当遇到Class类型的对象时,似乎会被忽略。
Gson将HashMap和Java类示例转换为JSON对象。

{
    "hash_key_1": {
        "jsonString": "json_string_instance_1",
        "classType": "my.class.Name1"
    },
    "hash_key_2": {
        "jsonString": "json_string_instance_2",
        "classType": "my.class.Name2"
    }
}
mrphzbgm

mrphzbgm2#

您需要为ClassData实现自己的自定义序列化程序,然后将其注册到Gson Builder。

public class ClassDataSerializerExample {
    static class ClassData {
        public String jsonString;
        public Class classType;

        public ClassData(String jsonString, Class classType) {
            this.jsonString = jsonString;
            this.classType = classType;
        }
    }

    static class ClassDataSerializer implements JsonSerializer<ClassData> {
        @Override
        public JsonElement serialize(ClassData src, Type typeOfSrc, JsonSerializationContext context) {
            return new JsonPrimitive(src.jsonString);
        }
    }

    public static void main(String[] args) {
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(ClassData.class, new ClassDataSerializer());

        HashMap<String, ClassData> map = new HashMap<>();
        map.put("key", new ClassData("key", String.class));

        Gson gson = gsonBuilder.create();
        String json = gson.toJson(map);

        System.out.println(json);
    }
}

输出:{“键”:“键”}
阅读更多信息:https://sites.google.com/site/gson/gson-user-guide#TOC-Writing-a-Serializer

相关问题