如何使用Gson序列化java.nio.file.Path?

Ale*_*ndr 11 java nio gson

java.lang.StackOverflowError试图序列化Object包含时得到java.nio.file.Path

即使我写道:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

并应用它:

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

我仍然无法序列化这个类:

public class ConstructorSetup {

    private Path appIconMimmapDirPathOnPc;

}
Run Code Online (Sandbox Code Playgroud)

Stacktrace :(完全在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)
Run Code Online (Sandbox Code Playgroud)

有解决方案吗

var*_*ren 11

你的问题是,这Path是一个interface.假设您使用了Paths.get("/")哪个将WindowsPath在我的Windows PC上创建类似的实例.现在,您必须告诉GSON如何反序列化此类型:

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())
Run Code Online (Sandbox Code Playgroud)

您可以采用的另一种方法是registerTypeHierarchyAdapter:

.registerTypeHierarchyAdapter(Path.class, new MyPathConverter())
Run Code Online (Sandbox Code Playgroud)

typeHierarchyAdapter的目的是覆盖当你想要一个类型的所有子类型的相同表示时的情况,这正是你的情况Path.

  • 谢谢你的解释!`registerTypeHierarchyAdapter` - 我需要的东西. (2认同)