2013-05-10 32 views
41

我有具有一定私有字段,並且在同一類擴展另一個類B,其也有一些私有字段;這些都是類A.A類聲明瞭多個JSON字段

public class A extends B { 
    private BigDecimal netAmountTcy; 
    private BigDecimal netAmountPcy; 
    private BigDecimal priceTo; 
    private String segment; 

    private BigDecimal taxAmountTcy; 
    private BigDecimal taxAmountPcy; 
    private BigDecimal tradeFeesTcy; 
    private BigDecimal tradeFeesPcy; 

// getter and setter for the above fields 

} 

和B類具有A級有一些私人fiedls這是在A級

現在,當我嘗試從A類我得到下面的異常上面創建的JSON字符串:

class com.hexgen.ro.request.A declares multiple JSON fields named netAmountPcy 

如何解決這一問題?

因爲他們是私人領域應該不會有任何問題,當我創建json字符串我猜,但我不知道。

我創建JSON字符串如下所示:

Gson gson = new Gson(); 
tempJSON = gson.toJson(obj); 

這裏obj是A類

+0

發表您的超級B級 – NPKR 2013-05-10 07:08:04

回答

46

的對象,因爲它們是私人領域不應該有任何問題,同時創造JSON字符串

我不認爲這個說法是真實的,GSON在序列化時查找對象的私有字段,這意味着包含所有超類的私有字段,並且當你有同名的字段時拋出一個錯誤。

如果有您不希望包括你有transient關鍵字,例如,以紀念它的任何特殊領域:

private transient BigDecimal tradeFeesPcy; 
+0

謝謝它的作品。但是,爲什麼@Expose註解Gson do not與superpreclass字段一起工作,並且會造成混淆? – Fakher 2017-05-19 15:19:10

+0

私人爲什麼重要?受保護的還不錯? – Tomer 2017-05-24 08:04:12

+1

@Fakher讓'@ Expose'正常工作,您需要設置'@Expose(serialize = false)'並確保在'GsonBuilder'對象上調用'excludeFieldsWithoutExposeAnnotation()'。 – bitsnaps 2018-02-12 10:49:12

46

這是有點晚了,但我遇到了這個完全一樣的問題,以及。唯一的問題是我無法修改超類,因爲該代碼不是我的。我解決這個問題的方法是創建一個排除策略,該策略跳過超類中具有相同名稱的字段的所有字段。這裏是我的那個類的代碼:

public class SuperclassExclusionStrategy implements ExclusionStrategy 
{ 
    public boolean shouldSkipClass(Class<?> arg0) 
    { 
     return false; 
    } 

    public boolean shouldSkipField(FieldAttributes fieldAttributes) 
    { 
     String fieldName = fieldAttributes.getName(); 
     Class<?> theClass = fieldAttributes.getDeclaringClass(); 

     return isFieldInSuperclass(theClass, fieldName);    
    } 

    private boolean isFieldInSuperclass(Class<?> subclass, String fieldName) 
    { 
     Class<?> superclass = subclass.getSuperclass(); 
     Field field; 

     while(superclass != null) 
     { 
      field = getField(superclass, fieldName); 

      if(field != null) 
       return true; 

      superclass = superclass.getSuperclass(); 
     } 

     return false; 
    } 

    private Field getField(Class<?> theClass, String fieldName) 
    { 
     try 
     { 
      return theClass.getDeclaredField(fieldName); 
     } 
     catch(Exception e) 
     { 
      return null; 
     } 
    } 
} 

我然後設置在構建器的序列化和反序列化排除策略如下:

builder.addDeserializationExclusionStrategy(new SuperclassExclusionStrategy()); 
    builder.addSerializationExclusionStrategy(new SuperclassExclusionStrategy()); 

希望這可以幫助別人!

+2

這是正確的答案,因爲我不想排除超類的對象被序列化,我只是不希望GSON排除擴展類的變量 – CQM 2014-02-28 17:07:57

+4

adrian;你美麗,美麗的男人。 – tipu 2014-05-23 05:12:26

+3

在我看來這是錯誤的方法。這樣你的json將包含來自超類的變量,並且子類的值將被隱藏。人們會期望相反;在json中有子類變量,並隱藏超類變量。 – Veda 2015-12-09 12:57:15

0

在我來說,我很愚蠢的註冊與X級的適配器,並嘗試序列化fromJson與Y艙:

 final GsonBuilder gsonBuilder = new GsonBuilder(); 
     gsonBuilder.registerTypeAdapter(Game.class, new TournamentSerializer()); 
     final Gson gson = gsonBuilder.create(); 

     createdTournament = gson.fromJson(jsonResponse.toString(), Tournament.class); 
5

,如果你有不同的領域同樣的錯誤信息也發生了,但他們有相同@SerializedName

@SerializedName("date_created") 
private Date DateCreated; 
@SerializedName("date_created") 
private Integer matchTime; 

做複製/粘貼你可以簡單地犯這樣的錯誤。所以,看看類及其祖先並檢查。

1

在proguard底部添加以下行。配置 (如果你在項目中使用ProGuard)

-keepclassmembers class * { 
    private <fields>;  
}