2014-01-09 31 views
0

我正在嘗試render列表爲jsonplay framework 1.2.x中。當我從網上搜索時,我發現使用Gosn。但它反正無濟於事。我需要在我的controller action中呈現任何object list作爲json。這是我的代碼和錯誤跟蹤。如何在播放框架1.2.x中將JSON呈現爲列表

@Entity(name="country") 
public class Country extends Model{ 
    public String name; 
    public String code; 

    @OneToMany(mappedBy="country", fetch=FetchType.EAGER, cascade = CascadeType.ALL) 
    public List<City> cities; 
} 

@Entity 
public class City extends Model{ 
    public String name; 
    public String code; 
    @ManyToOne 
    public Country country; 
} 


public static void ajaxGetCities(long countryid){ 
    List<City> cities = City.find("byCountry_id", countryid).fetch(); 
    renderJSON(cities); 
} 


at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:879) 
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60) 
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:879) 
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:96) 
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:60) 
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:68) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.write(ReflectiveTypeAdapterFactory.java:89) 
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:195) 
at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:879) 
+0

我沒有在堆棧跟蹤中看到異常的類型。雖然我懷疑這是一個循環參考問題。你的「城市」對象中有對象引用循環嗎?例如,City有一個對象一個引用,而對象A也有對象引用。 – dwi2

+0

我已通過添加國家和城市課程更新了我的問題。 – Emilla

+0

嘗試在Country類的城市中設置fetch = FetchType.LAZY。 – arbuzz

回答

1

這似乎是一個循環參考問題。當gson試圖在列表中序列化City對象(比如說City A)時,它找到Country對象,因此它也試圖序列化Country對象。但是,Country對象中有許多City對象引用,其中一個引用指向City A.因此,這裏有一個引用循環。

有兩種選擇,你的情況來解決循環引用:

A.在國家物體移除City對象的引用。

@OneToMany(mappedBy="country", fetch=FetchType.EAGER, cascade = CascadeType.ALL) 
    public List<City> cities; 

OneToMany是一種多餘的我,因爲我總能在城市對象的靜態方法找到國家城市。

B.請保留cities字段並執行CountrySerializer以防止循環引用。

public class CountrySerializer implements JsonSerializer<Country> { 

     public JsonElement serialize(User src, Type typeOfSrc, JsonSerializationContext context) { 
      Gson gson = new GsonBuilder() 
       .setExclusionStrategies(new LocalExclusionStrategy()).create(); 
      return gson.toJsonTree(src); 
     } 

     public static class LocalExclusionStrategy implements ExclusionStrategy { 
      public boolean shouldSkipClass(Class<?> clazz) { 
       return false; 
      } 

      public boolean shouldSkipField(FieldAttributes f) { 
       // add exlusion rules here: 
       // exclude field whose name is "cities" 
       return f.getName().toLowerCase().equals("cities"); 
      } 
     } 
    } 

使用它:

public static void ajaxGetCities(long countryid){ 
     List<City> cities = City.find("byCountry_id", countryid).fetch(); 
     renderJSON(cities, new CountrySerializer()); 
    } 

如果您在返回的對象結構複雜,你可以在使用多個串行器在同一時間。

renderJSON(cities, new CountrySerializer(), new CodeSerializer()); 
相關問題