2013-05-10 21 views
41

tôi có một hạng A trong đó có một số lĩnh vực tư nhân và cùng lớp kéo dài một lớp B mà cũng có một số lĩnh vực tư nhân mà là trong lớp A.lớp A kê khai nhiều lĩnh vực 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 

} 

và lớp B có có một số fiedls tin đó là trong lớp A

bây giờ khi tôi cố gắng để tạo ra chuỗi JSON từ trên lớp Một tôi nhận được ngoại lệ sau đây:

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

Làm thế nào để sửa lỗi này?

Vì chúng là trường riêng tư nên không có bất kỳ vấn đề nào trong khi tạo chuỗi json tôi đoán nhưng tôi không chắc chắn.

tôi tạo ra chuỗi json như sau:

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

đây obj là đối tượng của lớp Một

+0

gửi bạn siêu lớp B. – NPKR

Trả lời

46

Vì họ là những lĩnh vực tư nhân không nên có bất kỳ vấn đề trong khi tạo ra chuỗi json

Tôi không nghĩ rằng câu lệnh này là đúng, GSON tra cứu các trường riêng của đối tượng khi tuần tự hóa, nghĩa là tất cả các trường riêng của siêu lớp được bao gồm và khi bạn có trường có cùng tên ném một lỗi.

Nếu có bất kỳ lĩnh vực cụ thể bạn không muốn bao gồm bạn phải đánh dấu nó với transient từ khóa, ví dụ:

private transient BigDecimal tradeFeesPcy; 
+0

Cảm ơn bạn nó hoạt động. Nhưng tại sao chú thích @Expose của Gson không làm việc với trường siêu phân biệt và nó làm cho sự nhầm lẫn? – Fakher

+0

Tại sao tư nhân quan trọng? được bảo vệ tốt? – Tomer

+1

@Bạn muốn nhận '' Expose' hoạt động đúng cách bạn cần đặt '@Expose (serialize = false)' và đảm bảo gọi 'excludeFieldsWithoutExposeAnnotation()' trên đối tượng 'GsonBuilder' của bạn. – bitsnaps

46

Đây là hơi muộn, nhưng tôi chạy vào cùng một vấn đề này chính xác cũng . Điều duy nhất là tôi không thể sửa đổi siêu lớp vì mã đó không phải của tôi. Cách mà tôi giải quyết điều này là bằng cách tạo ra một chiến lược loại trừ bỏ qua bất kỳ trường nào có một trường có cùng tên trong một siêu lớp. Đây là mã của tôi cho lớp đó:

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

sau đó tôi thiết lập các chiến lược serialization và loại trừ Deserialization trong xây dựng như sau:

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

Hy vọng rằng đây sẽ giúp người!

+2

đây là câu trả lời đúng bởi vì tôi không muốn loại trừ đối tượng của siêu lớp khỏi việc được tuần tự hóa, tôi không muốn GSON loại trừ biến của lớp mở rộng là – CQM

+4

adrian; bạn đẹp, người đàn ông đẹp. – tipu

+3

Theo ý kiến ​​của tôi, đây là cách sai lầm. Bằng cách này, json của bạn sẽ chứa biến từ lớp siêu và giá trị của lớp con sẽ bị ẩn. Người ta hy vọng sẽ có nó theo cách khác; có biến subclass trong json và ẩn biến superclass. – Veda

0

Trong trường hợp của tôi, tôi đã câm, đủ để đăng ký một adapter với lớp X, và cố gắng để serialize fromJson với Y lớp:

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

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

Các thông báo lỗi tương tự cũng sẽ xảy ra nếu bạn có các lĩnh vực khác nhau, nhưng họ có cùng một @SerializedName.

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

Làm sao chép/dán bạn chỉ có thể mắc lỗi như vậy. Vì vậy, hãy nhìn vào lớp và tổ tiên của nó và kiểm tra điều đó.

1

Thêm các dòng sau ở cuối trình bảo vệ.cấu hình (nếu bạn đang sử dụng Proguard trong dự án)

-keepclassmembers class * { 
    private <fields>;  
} 
Các vấn đề liên quan