2017-04-06 41 views
0

如何設置超一流的「查找」的id屬性,名稱解析JSON時解析國家的JSON陣列 時設置超類屬性:如何使用GSON

[ {"ID":5, "CountryNameEN":"UK" }, {"ID":6, "CountryNameEN":"USA" } ] 

例如,當我調用get_lookups_countries()API與改造2 &解析響應與谷歌Gson庫,我想設置超類實例成員ID爲&名稱與派生類相同的值「國家」

@GET(Constants.LookUps.GET_COUNTRIES) Call<List<Country>> get_lookups_countries(); 
Gson gson = new GsonBuilder() 
      .setLenient() 
      .registerTypeAdapter(LookUp.class,new LookupsDeserializer()) 
      .create(); 

    HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); 
    logging.setLevel(HttpLoggingInterceptor.Level.BODY); 
    OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder(); 

    Retrofit retrofit = new Retrofit.Builder() 
      .baseUrl(BASE_URL) 
      .client(okHttpClient.build()) 
      .addConverterFactory(GsonConverterFactory.create(gson)) 
      .build(); 
    return retrofit.create(APIEndpointVatTax.class); 
public class LookUp { 
    int id; 
    String name; 
} 


public class Country extends LookUp { 

     @SerializedName("ID") 
     @Expose 
     private Integer iD; 

     @SerializedName("CountryNameEN") 
     @Expose 
     private String countryNameEN; 
} 
+0

Lookup ID和Country iD是不同的嗎? –

+0

不,相同的值 –

+1

那你爲什麼需要超類? –

回答

1

你似乎有一些問題,你的JSON映射:你想綁定的超類字段子類字段,然而這是哪裏的接口可能是你更好的選擇,因爲你的意圖只是詢問反序列化的對象的id和名稱。

我會做這樣的:

interface LookUp { 

    int getId(); 

    String getName(); 

} 
final class CountryByInterface 
     implements LookUp { 

    @SerializedName("ID") 
    private final Integer id = null; 

    @SerializedName("CountryNameEN") 
    private final String name = null; 

    @Override 
    public int getId() { 
     return id; 
    } 

    @Override 
    public String getName() { 
     return name; 
    } 

} 

所以它可以很容易使用(Java的8只爲演示目的):

final Gson gson = new Gson(); 
final Type countryListType = new TypeToken<List<CountryByInterface>>() { 
}.getType(); 
try (final Reader reader = getPackageResourceReader(Q43247712.class, "countries.json")) { 
    gson.<List<CountryByInterface>>fromJson(reader, countryListType) 
      .stream() 
      .map(c -> c.getId() + "=>" + c.getName()) 
      .forEach(System.out::println); 
} 

如果出於某種正當理由你確實需要超級類來持有這樣的領域,你必須實現後處理器(靈感來自PostConstructAdapterFactory)。再說了,

abstract class AbstractLookUp { 

    int id; 
    String name; 

    abstract int getId(); 

    abstract String getName(); 

    final void postSetUp() { 
     id = getId(); 
     name = getName(); 
    } 

} 
final class CountryByClass 
     extends AbstractLookUp { 

    @SerializedName("ID") 
    private final Integer id = null; 

    @SerializedName("CountryNameEN") 
    private final String name = null; 

    @Override 
    int getId() { 
     return id; 
    } 

    @Override 
    String getName() { 
     return name; 
    } 

} 
final Gson gson = new GsonBuilder() 
     .registerTypeAdapterFactory(new TypeAdapterFactory() { 
      @Override 
      public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) { 
       // Check if it's a class we can handle: AbstractLookUp 
       if (AbstractLookUp.class.isAssignableFrom(typeToken.getRawType())) { 
        // Get the downstream parser for the given type 
        final TypeAdapter<T> delegateTypeAdapter = gson.getDelegateAdapter(this, typeToken); 
        return new TypeAdapter<T>() { 
         @Override 
         public void write(final JsonWriter out, final T value) 
           throws IOException { 
          delegateTypeAdapter.write(out, value); 
         } 

         @Override 
         public T read(final JsonReader in) 
           throws IOException { 
          // Deserialize it as an AbstractLookUp instance 
          final AbstractLookUp abstractLookUp = (AbstractLookUp) delegateTypeAdapter.read(in); 
          // And set it up 
          abstractLookUp.postSetUp(); 
          @SuppressWarnings("unchecked") 
          final T result = (T) abstractLookUp; 
          return result; 
         } 
        }; 
       } 
       return null; 
      } 
     }) 
     .create(); 
final Type countryListType = new TypeToken<List<CountryByClass>>() { 
}.getType(); 
try (final Reader reader = getPackageResourceReader(Q43247712.class, "countries.json")) { 
    gson.<List<CountryByClass>>fromJson(reader, countryListType) 
      .stream() 
      .map(c -> ((AbstractLookUp) c).id + "=>" + ((AbstractLookUp) c).name) 
      .forEach(System.out::println); 
} 

兩個例子都產生

5 = >英國
6 = >美國

但是我覺得第一種方法更好地設計和多更容易使用,哪裏第二個演示如何配置Gson來實現複雜的(de)序列化策略。

+0

最佳解決方案!謝謝Lyubomyr,你節省了我的時間。 感謝您的支持和幫助。 –

+0

@FarisAbuSaleem沒問題,不客氣。 –