2011-11-21 24 views
69

साथ JSON को पार्स, जबकि यह एक पिछले प्रश्न है कि मैं यहाँ पहलेEnums का उपयोग GSON

JSON parsing using Gson

मैं एक ही JSON पार्स करने के लिए कोशिश कर रहा हूँ, लेकिन अब मैं अपने वर्गों में थोड़ा बदल गया है पूछा से संबंधित है ।

{ 
    "lower": 20, 
    "upper": 40, 
    "delimiter": " ", 
    "scope": ["${title}"] 
} 

मेरी कक्षा अब लगता है कि:

public class TruncateElement { 

    private int lower; 
    private int upper; 
    private String delimiter; 
    private List<AttributeScope> scope; 

    // getters and setters 
} 


public enum AttributeScope { 

    TITLE("${title}"), 
    DESCRIPTION("${description}"), 

    private String scope; 

    AttributeScope(String scope) { 
     this.scope = scope; 
    } 

    public String getScope() { 
     return this.scope; 
    } 
} 

इस कोड को एक अपवाद फेंकता है,

com.google.gson.JsonParseException: The JsonDeserializer EnumTypeAdapter failed to deserialized json object "${title}" given the type class com.amazon.seo.attribute.template.parse.data.AttributeScope 
at 

अपवाद क्योंकि मेरे पिछले प्रश्न का हल अनुसार, समझा जा सकता है, GSON है एनम ऑब्जेक्ट्स को वास्तव में

${title}("${title}"), 
${description}("${description}"); 
के रूप में बनाया जा रहा है

लेकिन चूंकि यह वाक्य रचनात्मक रूप से असंभव है, तो अनुशंसित समाधान, कामकाज क्या हैं?

उत्तर

37

the documentation for Gson से:

Gson Enums के लिए डिफ़ॉल्ट क्रमबद्धता और अक्रमांकन प्रदान करता है ... आप डिफ़ॉल्ट प्रदर्शन बदलने के लिए पसंद करेंगे, तो आप ऐसा GsonBuilder.registerTypeAdapter के माध्यम से एक प्रकार एडाप्टर पंजीकरण से कर सकते हैं (प्रकार, वस्तु)।

निम्नलिखित एक ऐसा दृष्टिकोण है।

import java.io.FileReader; 
import java.lang.reflect.Type; 
import java.util.List; 

import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 
import com.google.gson.JsonDeserializationContext; 
import com.google.gson.JsonDeserializer; 
import com.google.gson.JsonElement; 
import com.google.gson.JsonParseException; 

public class GsonFoo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    GsonBuilder gsonBuilder = new GsonBuilder(); 
    gsonBuilder.registerTypeAdapter(AttributeScope.class, new AttributeScopeDeserializer()); 
    Gson gson = gsonBuilder.create(); 

    TruncateElement element = gson.fromJson(new FileReader("input.json"), TruncateElement.class); 

    System.out.println(element.lower); 
    System.out.println(element.upper); 
    System.out.println(element.delimiter); 
    System.out.println(element.scope.get(0)); 
    } 
} 

class AttributeScopeDeserializer implements JsonDeserializer<AttributeScope> 
{ 
    @Override 
    public AttributeScope deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 
     throws JsonParseException 
    { 
    AttributeScope[] scopes = AttributeScope.values(); 
    for (AttributeScope scope : scopes) 
    { 
     if (scope.scope.equals(json.getAsString())) 
     return scope; 
    } 
    return null; 
    } 
} 

class TruncateElement 
{ 
    int lower; 
    int upper; 
    String delimiter; 
    List<AttributeScope> scope; 
} 

enum AttributeScope 
{ 
    TITLE("${title}"), DESCRIPTION("${description}"); 

    String scope; 

    AttributeScope(String scope) 
    { 
    this.scope = scope; 
    } 
} 
+0

बहुत बहुत धन्यवाद। यह काम किया। –

+0

यह काम करता है !! धन्यवाद!! –

20

उपयोग एनोटेशन @SerializedName:

@SerializedName("${title}") 
TITLE, 
@SerializedName("${description}") 
DESCRIPTION 
195

मैं थोड़ा नाज़िक/user2724653 जवाब (मेरे मामले के लिए) का विस्तार करना चाहते हैं। - स्थिति मान पर निर्भर json फ़ाइल में

public class Item { 
    @SerializedName("status") 
    private Status currentState = null; 

    // other fields, getters, setters, constructor and other code... 

    public enum Status { 
     @SerializedName("0") 
     BUY, 
     @SerializedName("1") 
     DOWNLOAD, 
     @SerializedName("2") 
     DOWNLOADING, 
     @SerializedName("3") 
     OPEN 
    } 
} 

आपके पास सिर्फ एक क्षेत्र "status": "N",, जहां एन = 0,1,2,3: यहाँ एक जावा कोड है। तो यह सब है, GSON नेस्टेड enum कक्षा के मानों के साथ ठीक काम करता है। मेरे मामले में मैं json सरणी से Items की एक सूची पार्स किया है:

List<Item> items = new Gson().<List<Item>>fromJson(json, 
              new TypeToken<List<Item>>(){}.getType()); 
+14

यह उत्तर पूरी तरह से हल करता है, प्रकार एडाप्टर के लिए कोई ज़रूरत नहीं है! –

+1

यहां लाइवसेवर :) –

+0

@ enerializedName (एन) enum के लिए नौकरी किया;) – GuilhE

4

GSON संस्करण के साथ 2.2.2 enum मार्शल और आसानी से unmarshalled कर दिया जाएगा।

import com.google.gson.annotations.SerializedName; 

enum AttributeScope 
{ 
    @SerializedName("${title}") 
    TITLE("${title}"), 

    @SerializedName("${description}") 
    DESCRIPTION("${description}"); 

    private String scope; 

    AttributeScope(String scope) 
    { 
    this.scope = scope; 
    } 

    public String getScope() { 
    return scope; 
    } 
} 
0

तुम सच में Enum के क्रमसूचक मूल्य उपयोग करने के लिए एक प्रकार एडाप्टर कारखाने Gson के डिफ़ॉल्ट कारखाना ओवरराइड करने के लिए रजिस्टर कर सकते हैं।

public class EnumTypeAdapter <T extends Enum<T>> extends TypeAdapter<T> { 
    private final Map<Integer, T> nameToConstant = new HashMap<>(); 
    private final Map<T, Integer> constantToName = new HashMap<>(); 

    public EnumTypeAdapter(Class<T> classOfT) { 
     for (T constant : classOfT.getEnumConstants()) { 
      Integer name = constant.ordinal(); 
      nameToConstant.put(name, constant); 
      constantToName.put(constant, name); 
     } 
    } 
    @Override public T read(JsonReader in) throws IOException { 
     if (in.peek() == JsonToken.NULL) { 
      in.nextNull(); 
      return null; 
     } 
     return nameToConstant.get(in.nextInt()); 
    } 

    @Override public void write(JsonWriter out, T value) throws IOException { 
     out.value(value == null ? null : constantToName.get(value)); 
    } 

    public static final TypeAdapterFactory ENUM_FACTORY = new TypeAdapterFactory() { 
     @SuppressWarnings({"rawtypes", "unchecked"}) 
     @Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) { 
      Class<? super T> rawType = typeToken.getRawType(); 
      if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) { 
       return null; 
      } 
      if (!rawType.isEnum()) { 
       rawType = rawType.getSuperclass(); // handle anonymous subclasses 
      } 
      return (TypeAdapter<T>) new EnumTypeAdapter(rawType); 
     } 
    }; 
} 

फिर कारखाने को पंजीकृत करें।

Gson gson = new GsonBuilder() 
       .registerTypeAdapterFactory(EnumTypeAdapter.ENUM_FACTORY) 
       .create(); 
संबंधित मुद्दे