2016-05-01 28 views
8

uzyskać java.lang.StackOverflowError podczas próby serializacji Object że zawiera java.nio.file.PathJak serializować java.nio.file.Path z Gsonem?

nawet kiedy pisał:

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

i zastosować go:

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

Wciąż nie mogę serializacji tej klasy:

public class ConstructorSetup { 

    private Path appIconMimmapDirPathOnPc; 

} 

StackTrace: (pełne 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) 

Każde rozwiązanie?

+1

Proszę również pokazać stacktrace 'StackOverflowError'. – RAnders00

+0

@ RAnders00 done. – Alexandr

Odpowiedz

8

Twój problem polega na tym, że Path to interface. Załóżmy, że użyłeś Paths.get("/"), która stworzy instancję podobną do WindowsPath na moim komputerze z systemem Windows. Teraz trzeba powiedzieć GSON jak deserializowania tego typu:

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

Innym podejściem można przejść z ma registerTypeHierarchyAdapter:

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

Celem typeHierarchyAdapter ma obejmować przypadek, gdy chcesz taka sama reprezentacja dla wszystkich podtypów danego typu, która jest dokładnie twoja z Path.

+2

Dzięki za wspaniałe wyjaśnienie! 'registerTypeHierarchyAdapter' - czego potrzebuję. – Alexandr