How to serialize java.nio.file.Path with Gson?

断了今生、忘了曾经 提交于 2020-01-03 07:18:11

问题


I get java.lang.StackOverflowError when trying to serialize Object that contains java.nio.file.Path

Even when i wrote:

public class PathConverter implements JsonDeserializer<Path>, JsonSerializer<Path> {
    @Override
    public Path deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        return Paths.get(jsonElement.getAsString());
    }

    @Override
    public JsonElement serialize(Path path, Type type, JsonSerializationContext jsonSerializationContext) {
        return new JsonPrimitive(path.toString());
    }
}

and apply it:

    String json = new GsonBuilder()
            .registerTypeAdapter(Path.class, new PathConverter())
            .create()
            .toJson(constructorSetup, new TypeToken<ConstructorSetup>() {}.getType());

I still can't serialize this class:

public class ConstructorSetup {

    private Path appIconMimmapDirPathOnPc;

}

Stacktrace: (full on pastebin)

Exception in thread "main" java.lang.StackOverflowError
    at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
    at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:375)
    at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
        ...
    at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:380)
    at com.google.gson.internal.$Gson$Types.resolve($Gson$Types.java:355)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:117)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
    at com.google.gson.Gson.getAdapter(Gson.java:356)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
    at com.google.gson.Gson.getAdapter(Gson.java:356)
        ...
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.<init>(ReflectiveTypeAdapterFactory.java:82)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
    at com.google.gson.Gson.getAdapter(Gson.java:356)

Any solution?


回答1:


Your problem is that Path is an interface. Let's suppose you used Paths.get("/") which will create instance of something like WindowsPath on my Windows PC. Now, you have to tell GSON how to deserialize this type:

ConstructorSetup setup = new ConstructorSetup();
setup.setAppIconMimmapDirPathOnPc(Paths.get("/"));

// here we get actual class type of our Path object
Class classT = setup.getAppIconMimmapDirPathOnPc().getClass();

Gson gson = new GsonBuilder().registerTypeAdapter(classT, new MyPathConverter())

Another approach you can go with is to registerTypeHierarchyAdapter:

.registerTypeHierarchyAdapter(Path.class, new MyPathConverter())

The purpose of typeHierarchyAdapter is to cover the case when you want the same representation for all subtypes of a type, which is exactly your case with Path.



来源:https://stackoverflow.com/questions/36964995/how-to-serialize-java-nio-file-path-with-gson

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!