2016-05-01 13 views
8

ottengo java.lang.StackOverflowError quando si cerca di serializzare Object che contiene java.nio.file.PathCome serializzare java.nio.file.Path con Gson?

Anche quando ho scritto:

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()); 
    } 
} 

e applicarlo:

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

Non riesco ancora a serializzare questa classe:

public class ConstructorSetup { 

    private Path appIconMimmapDirPathOnPc; 

} 

Stacktrace: (completo su 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) 

Qualsiasi soluzione?

+1

Mostrare anche lo stacktrace 'StackOverflowError'. – RAnders00

+0

@ RAnders00 fatto. – Alexandr

risposta

8

Il tuo problema è che Path è un interface. Supponiamo che tu abbia usato Paths.get("/") che creerà un'istanza di qualcosa come WindowsPath sul mio PC Windows. Ora, dovete dire GSON come deserializzare questo tipo:

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()) 

Un altro approccio si può andare con è quello di registerTypeHierarchyAdapter:

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

Lo scopo di typeHierarchyAdapter è quello di coprire il caso in cui si desidera che il stessa rappresentazione per tutti i sottotipi di un tipo, che è esattamente il tuo caso con Path.

+2

Grazie per l'ottima spiegazione! 'registerTypeHierarchyAdapter' - quello di cui ho bisogno. – Alexandr

Problemi correlati