2013-06-07 29 views
6

Gson ile bir JSONArray ürününü deserialize etmeye çalışıyorum, değer 'in_wanted' değeri bir boolean veya JSONObject olabilir.Gson değişken değer türleri ile json desterize json

boolean olarak in_wanted:

{ 
"movies": [ 
     { 
      "title": "example boolean", 
      "in_wanted": false 
     } 
    ]   
} 

JSONObject olarak in_wanted:

{ 
"movies": [ 
     { 
      "title": "example object", 
      "in_wanted": { 
       "profile": { 
        "value": false 
       } 
      } 
     } 
    ]   
} 

Ben mevcut olduğunda ona nesne gerekir ve değeri "in_wanted" her ne zaman i return null bir deserializer gereken bir olduğunu boole. Bunu Gson ile yapmanın en iyi yolu ne olurdu?

+0

sonra safça GSON deserializer çalışmasına izin deneyin bir sınıfa haritalama ediyorsanız, bu boş olarak başvuru izin vermelisiniz. – Pragmateek

cevap

10

Bunu yapabilirsin özel deserializer ile. Başlangıçta JSON'unuzu temsil edebilecek bir veri modeli oluşturmalıyız.

class ProfileJsonDeserializer implements JsonDeserializer<Profile> { 
    @Override 
    public Profile deserialize(JsonElement jsonElement, Type type, 
      JsonDeserializationContext context) throws JsonParseException { 
     if (jsonElement.isJsonPrimitive()) { 
      return null; 
     } 

     return context.deserialize(jsonElement, JsonProfile.class); 
    } 
} 

class JsonProfile extends Profile { 

} 

JsonProfile sınıfına bir göz atın: Hepimizin gerekli sınıfları olduğunda
class JsonEntity { 

    private List<Movie> movies; 

    public List<Movie> getMovies() { 
     return movies; 
    } 

    public void setMovies(List<Movie> movies) { 
     this.movies = movies; 
    } 

    @Override 
    public String toString() { 
     return "JsonEntity [movies=" + movies + "]"; 
    } 
} 

class Movie { 

    private String title; 
    private Profile in_wanted; 

    public String getTitle() { 
     return title; 
    } 

    public void setTitle(String title) { 
     this.title = title; 
    } 

    public Profile getIn_wanted() { 
     return in_wanted; 
    } 

    public void setIn_wanted(Profile in_wanted) { 
     this.in_wanted = in_wanted; 
    } 

    @Override 
    public String toString() { 
     return "Movie [title=" + title + ", in_wanted=" + in_wanted + "]"; 
    } 
} 

class Profile { 

    private boolean value; 

    public boolean isValue() { 
     return value; 
    } 

    public void setValue(boolean value) { 
     this.value = value; 
    } 

    @Override 
    public String toString() { 
     return String.valueOf(value); 
    } 
} 

Şimdi yeni özel deserializer uygulamalıdır. "Deserialization loop" (zorlu bölüm) den kaçınmak için onu yaratmak zorundayız.

Ve şimdi test yöntemine bizim çözüm test edebilirsiniz:

GsonBuilder builder = new GsonBuilder(); 
builder.registerTypeAdapter(Profile.class, new ProfileJsonDeserializer()); 
Gson gson = builder.create(); 

JsonEntity jsonEntity = gson.fromJson(new FileReader("/tmp/json.txt"), 
     JsonEntity.class); 
System.out.println(jsonEntity); 
+2

@Meatje: Bu, yorumumda bahsettiğim diğer bir olasılık ... – MikO

+0

Bu, hile yaptı çünkü manuel ayrıştırma, @MikO'dan şüphelenilen büyük bir görev olurdu. Yardım için ikinize de çok teşekkürler! – Meatje

3

Bir manuel ayrıştırma yapabilirdi, gibi bir şey:

JsonParser parser = new JsonParser(); 
JsonObject rootObject = parser.parse(yourJsonString).getAsJsonObject(); 
JsonObject movieObject = rootObject 
          .getAsJsonArray("movies") 
          .get(0).getAsJsonObject(); 
JsonElement inWantedElement = movieObject.get("in_wanted"); 

//Check if "in_wanted" element is a boolean or an object 
if (inWantedElement.isJsonObject()) { 
    //Process the element as an object... 
    //for example get the element "value"... 
    boolean value = inWantedElement 
         .getAsJsonObject() 
         .getAsJsonObject("profile") 
         .getAsJsonPrimitive("value") 
         .getAsBoolean(); 
} 
else if (inWantedElement.isJsonPrimitive()) { 
    //Process the element as a boolean... 
    boolean inWanted = inWantedElement.getAsBoolean(); 
} 

Not: türlerinde JsonObject, JsonArray, JsonElement ilgili bilgi için Gson API documentation bakınız, vb ...

+0

Bunu sadece in_antual değeri için yapmak mümkün mü? Bu yüzden dizideki diğer değerler için elle ayrıştırma yazmak zorunda kalmam (varsayılan desperizatörün iyi bir şekilde ayrıştırılması). – Meatje

+1

@Meatje: Sanırım özel bir desperizer yazabilen bir olasılık var, ama bunu yazmadan önce, diğer çözümün bundan daha kolay olmayacağını ve bu JSON yanıtlarına sahip olmanızın daha iyi olduğunu düşünüyorum. .. ya da gerçek JSON yanıtlarınızın sadece küçük bir bölümünü dahil ettiniz mi? – MikO