如何使用Gson序列化java.nio.file.Path? [英] How to serialize java.nio.file.Path with Gson?

查看:219
本文介绍了如何使用Gson序列化java.nio.file.Path?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



即使我写道:

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

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

并应用它:

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

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

  public class ConstructorSetup {

private Path appIconMimmapDirPathOnPc;


$ / code $ / pre
$ b $

Stacktrace :(完整版 pastebin

 线程main java.lang.StackOverflowError 
,位于com.google.gson.internal。$ Gson $ Types.resolve($ Gson $ Types.java:380)
,位于com.google.gson.internal。$ Gson $ Types.resolve($ Gson $ Types.java:375)
在com.google.gson.internal。$ Gson $ Types.resolve($ Gson $ Types.java:380)
...
在com.google.gson.internal。$ Gson $ Types.resolve($ Gson $ Types.java:380)
在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)
在com.google.gson.Gson.getAdapter(Gson.java:356)
在com.google.gson.internal.bind.ReflectiveTypeAdapterFact ory $ 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)
,com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
,位于com.google.gson。 Gson.getAdapter(Gson.java:356)
...
在com.google.gson.internal.bind.ReflectiveTypeAdapterFactory $ 1.< init>(ReflectiveTypeAdapterFactory.java:82)
com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:81)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:118)
在com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:72)
at com.google.gson.Gson.getAdapter(Gson.java:356)

任何解决方案?

解决方案

您的问题在于 Path 是接口。让我们假设你使用了 Paths.get(/),它将在我的Windows PC上创建类似于 WindowsPath 的实例。现在,你必须告诉GSON如何反序列化这种类型:

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

//这里我们得到了我们Path对象的实际类类型
Class classT = setup.getAppIconMimmapDirPathOnPc()。getClass();

gson gson = new GsonBuilder()。registerTypeAdapter(classT,new MyPathConverter())

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

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

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


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?

解决方案

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.

这篇关于如何使用Gson序列化java.nio.file.Path?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆