2016-04-06 1 views
2

どこが間違っているのか分かりません。Moshi JsonAdapter.Factoryでデシリアライズするときにフィールド値を失う

final class Data { 
    final int num; 

    Data(int num) { 
    this.num = num; 
    } 

    static final class Wrapper { 
    final List<Data> data; 
    final long meta; 

    Wrapper(List<Data> data, long meta) { 
     this.data = data; 
     this.meta = meta; 
    } 
    } 
} 

WrapperからDataを引き出すために、私の工場:

私の単純なモデルは以下のようになり

final class ObjectAsListJsonAdapterFactory implements JsonAdapter.Factory { 
    @Override public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { 
    if (!List.class.isAssignableFrom(Types.getRawType(type))) { 
     return null; 
    } 
    JsonAdapter<List<Object>> listDelegate = moshi.nextAdapter(this, type, annotations); 
    Type innerType = Types.collectionElementType(type, List.class); 
    JsonAdapter<Object> objectDelegate = moshi.adapter(innerType, annotations); 
    return new ListJsonAdapter<>(listDelegate, objectDelegate); 
    } 

    static final class ListJsonAdapter<T> extends JsonAdapter<List<T>> { 
    private final JsonAdapter<List<T>> listDelegate; 
    private final JsonAdapter<T> objectDelegate; 

    ListJsonAdapter(JsonAdapter<List<T>> listDelegate, JsonAdapter<T> objectDelegate) { 
     this.listDelegate = listDelegate; 
     this.objectDelegate = objectDelegate; 
    } 

    @Override public List<T> fromJson(JsonReader jsonReader) throws IOException { 
     if (jsonReader.peek() == JsonReader.Token.BEGIN_OBJECT) { 
     return Collections.singletonList(objectDelegate.fromJson(jsonReader)); 
     } else { 
     return listDelegate.fromJson(jsonReader); 
     } 
    } 

    @Override public void toJson(JsonWriter jsonWriter, List<T> list) throws IOException { 
     listDelegate.toJson(jsonWriter, list); 
    } 
    } 
} 

が、私は実行すると:

String json = "{\n" 
    + " \"data\": [\n" 
    + " {\n" 
    + "  \"num\": 5\n" 
    + " }\n" 
    + " ],\n" 
    + " \"meta\": 21\n" 
    + "}"; 
Moshi moshi = new Moshi.Builder().add(new ObjectAsListJsonAdapterFactory()).build(); 
ParameterizedType type = Types.newParameterizedType(List.class, Data.class); 
JsonAdapter<List<Data>> adapter = moshi.adapter(type); 
List<Data> expected = adapter.fromJson(json); 

expectedは含まれてい1つのDatanum値のフィールド0

私には何が欠けていますか?

答えて

1

このフィールドはデフォルト値を持っています。そのフィールドは、そのJSONの希望のJsonAdapter.Factoryではないからです。そのFactoryは単一の配列アイテムのようなオブジェクトを作ろうとしています。 これはあなたが望むアンラップです:

static final class DataUnwrapperAdapterFactory implements JsonAdapter.Factory { 
    @Override 
    public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { 
    if (!List.class.isAssignableFrom(Types.getRawType(type))) { 
     return null; 
    } 
    if (!Data.class.isAssignableFrom(Types.getRawType(Types.collectionElementType(type, List.class)))) { 
     return null; 
    } 
    JsonAdapter<List<Data>> listDelegate = moshi.nextAdapter(this, type, annotations); 
    JsonAdapter<Data.Wrapper> wrapperDelegate = moshi.adapter(Data.Wrapper.class, annotations); 
    return new DataUnwrapperAdapter(listDelegate, wrapperDelegate); 
    } 

    static final class DataUnwrapperAdapter extends JsonAdapter<List<Data>> { 
    private final JsonAdapter<List<Data>> listDelegate; 
    private final JsonAdapter<Data.Wrapper> wrapperDelegate; 

    DataUnwrapperAdapter(JsonAdapter<List<Data>> listDelegate, 
     JsonAdapter<Data.Wrapper> wrapperDelegate) { 
     this.listDelegate = listDelegate; 
     this.wrapperDelegate = wrapperDelegate; 
    } 

    @Override public List<Data> fromJson(JsonReader jsonReader) throws IOException { 
     if (jsonReader.peek() == JsonReader.Token.BEGIN_OBJECT) { 
     Data.Wrapper wrapper = wrapperDelegate.fromJson(jsonReader); 
     return wrapper.data; 
     } else { 
     return listDelegate.fromJson(jsonReader); 
     } 
    } 

    @Override public void toJson(JsonWriter jsonWriter, List<Data> list) throws IOException { 
     listDelegate.toJson(jsonWriter, list); 
    } 
    } 
} 

、次の操作を実行できます。

String json = "{\n" 
    + " \"other_garbage\": \"hiya\",\n" 
    + " \"data\": [\n" 
    + " {\n" 
    + "  \"num\": 5\n" 
    + " }\n" 
    + " ],\n" 
    + " \"meta\": 21\n" 
    + "}"; 
Moshi moshi = new Moshi.Builder().add(new DataUnwrapperAdapterFactory()).build(); 
ParameterizedType type = Types.newParameterizedType(List.class, Data.class); 
JsonAdapter<List<Data>> adapter = moshi.adapter(type); 
List<Data> expected = adapter.fromJson(json); 

この溶液に取得するためのジェイクとジェシーに(いつものように)巨大な感謝を。

関連する問題