2016-05-01 24 views
8

tôi nhận được java.lang.StackOverflowError khi cố gắng serialize Object chứa java.nio.file.PathLàm thế nào để tuần tự hóa java.nio.file.Path với Gson?

Ngay cả khi tôi đã viết:

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

và áp dụng nó:

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

tôi vẫn không thể serialize lớp này:

public class ConstructorSetup { 

    private Path appIconMimmapDirPathOnPc; 

} 

Stacktrace: (đầy đủ trên 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) 

Bất kỳ giải pháp nào?

+1

Cũng vui lòng hiển thị ngăn xếp ngăn xếp 'StackOverflowError'. – RAnders00

+0

@ RAnders00 đã hoàn thành. – Alexandr

Trả lời

8

Vấn đề của bạn là Pathinterface. Giả sử bạn đã sử dụng Paths.get("/") để tạo một phiên bản giống như WindowsPath trên máy tính Windows của tôi. Bây giờ, bạn phải nói với GSON làm thế nào để deserialize loại:

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

Một cách tiếp cận bạn có thể đi với là registerTypeHierarchyAdapter:

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

Mục đích của typeHierarchyAdapter là để trang trải các trường hợp khi bạn muốn đại diện tương tự cho tất cả các loại phụ của một loại, chính xác là trường hợp của bạn với Path.

+2

Cảm ơn lời giải thích tuyệt vời! 'registerTypeHierarchyAdapter' - những gì tôi cần. – Alexandr

Các vấn đề liên quan