2017-10-16 9 views
0

Dans mon application Android (écrite en Kotlin), j'ai besoin de transformer du JSON en une chaîne en carte de hachage MainObject. Voici à quoi ressemble le JSON:JSON à HashMap avec des objets utilisant Gson

{ 
    "a": { 
     "name": "A", 
     "some_int": "2", 
     "some_string": "string", 
     "some_bool": false, 
     "some_string_arr": [ 
      "str1", 
      "str2" 
     ], 
     "sub_obj_arr": [ 
      { 
       "obj_name": "d", 
       "some_obj_string": "s" 
      } 
     ] 
    }, 
    "b": { 
     "name": "B", 
     "some_int": "4", 
     "some_string": "string", 
     "some_bool": false, 
     "some_string_arr": [ 
      "str5", 
      "str6" 
     ] 
    } 
} 

J'ai créé quelques objets pour vous aider.

class MainObject { 
    @SerializedName("name") 
    val name: String? = null 

    @SerializedName("some_int") 
    val someInt: Int? = null 

    @SerializedName("some_string") 
    val someString: String? = null 

    @SerializedName("some_bool") 
    val someBool: Boolean = false 

    @SerializedName("some_string_arr") 
    val someStringArr: List<String>? = null 

    @SerializedName("sub_obj_arr") 
    val someObjArr: List<SubObject>? = null 
} 

class SubObject { 
    @SerializedName("obj_name") 
    val objName: String? = null 

    @SerializedName("some_obj_string") 
    val someObjString: String? = null 
} 

Comment puis-je convertir en un type de HashMap<String, MainObject>? J'ai essayé d'utiliser un TypeToken comme décrit here, mais j'obtenais l'erreur "attendu commencer l'objet mais était la chaîne".

Des idées?

MISE À JOUR

Je lis aussi dans les données JSON localement via la solution décrite here

Error Log

10-15 20:06:42.771 10328-10328/xxx E/AndroidRuntime: FATAL EXCEPTION: main 
    Process: xxx, PID: 10328 
    java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
     at android.app.ActivityThread.-wrap11(Unknown Source:0) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
     at android.os.Handler.dispatchMessage(Handler.java:105) 
     at android.os.Looper.loop(Looper.java:164) 
     at android.app.ActivityThread.main(ActivityThread.java:6541) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 
    Caused by: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ 
     at com.google.gson.Gson.fromJson(Gson.java:900) 
     at com.google.gson.Gson.fromJson(Gson.java:853) 
     at com.google.gson.Gson.fromJson(Gson.java:802) 
     at xxx.onCreate(BottomNavigation.kt:48) 
     at android.app.Activity.performCreate(Activity.java:6975) 
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213) 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)  
     at android.app.ActivityThread.-wrap11(Unknown Source:0)  
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)  
     at android.os.Handler.dispatchMessage(Handler.java:105)  
     at android.os.Looper.loop(Looper.java:164)  
     at android.app.ActivityThread.main(ActivityThread.java:6541)  
     at java.lang.reflect.Method.invoke(Native Method)  
     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)  
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)  
    Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ 
     at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385) 
     at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:183) 
     at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145) 
     at com.google.gson.Gson.fromJson(Gson.java:888) 
     at com.google.gson.Gson.fromJson(Gson.java:853)  
     at com.google.gson.Gson.fromJson(Gson.java:802)  
     at xxx.onCreate(BottomNavigation.kt:48)  
     at android.app.Activity.performCreate(Activity.java:6975)  
     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)  
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)  
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)  
     at android.app.ActivityThread.-wrap11(Unknown Source:0)  
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)  
     at android.os.Handler.dispatchMessage(Handler.java:105)  
     at android.os.Looper.loop(Looper.java:164)  
     at android.app.ActivityThread.main(ActivityThread.java:6541)  
     at java.lang.reflect.Method.invoke(Native Method)  
     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)  
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)  

Mise à jour 2

La question réelle Quelque chose ne va pas avec la façon dont je suis ding dans mon fichier JSON local. Le code que j'utilise est la suivante:

val input = this.resources.openRawResource(R.raw.json) 
val json = try { 
    val size = input.available() 
    val buffer = ByteArray(size) 
    input.read(buffer) 
    input.close() 
    String(buffer) 
} catch (ex: IOException) { 
    ex.printStackTrace() 
    null 
} 

Ce qui me donne ces personnages étranges quand j'imprimer le JSON à la console:

10-15 23: 55: 11,911 3351-3351/xxx I/Système .out: {

10-15 23: 55: 11.911 3351-3351/xxx I/System.out: " a " : {

Aucune idée de pourquoi.

+0

Veuillez partager le journal des erreurs dans son intégralité. – Joshua

+0

Mis à jour avec le journal des erreurs –

Répondre

1

Je ne sais pas pourquoi vous avez une erreur. Je suis capable d'analyser le JSON avec le code suivant.

val gson = GsonBuilder().create() 
val type = object:TypeToken<Map<String, MainObject>>(){}.type 
val result = gson.fromJson<Map<String, MainObject>>("{ \"a\": { \"name\": \"A\", \"some_int\": \"2\", \"some_string\": \"string\", \"some_bool\": false, \"some_string_arr\": [ \"str1\", \"str2\" ], \"sub_obj_arr\": [ { \"obj_name\": \"d\", \"some_obj_string\": \"s\" } ] }, \"b\": { \"name\": \"B\", \"some_int\": \"4\", \"some_string\": \"string\", \"some_bool\": false, \"some_string_arr\": [ \"str5\", \"str6\" ] } }", type) 
+0

Hmm, intéressant. Merci d'avoir fait ce test pour moi. Cela me fait penser que quelque chose ne va pas avec la façon dont je lis dans le fichier JSON lui-même. –

0

D'accord, avec l'aide des autres je me suis dit que la question n'a pas été avec Gson ou mon JSON ou quoi que ce soit. C'était comme je le lisais dans la mémoire. Le code que j'utilisais était:

val input = this.resources.openRawResource(R.raw.json) 
val json = try { 
    val size = input.available() 
    val buffer = ByteArray(size) 
    input.read(buffer) 
    input.close() 
    String(buffer) 
} catch (ex: IOException) { 
    ex.printStackTrace() 
    null 
} 

Cependant, String(buffer) par défaut à utiliser UTF_8 charset. Pour que le mien fonctionne, j'avais besoin d'utiliser un jeu de caractères UTF_16. Le changement de travail utilisait String(buffer, Charsets.UTF_16).