web-dev-qa-db-fra.com

Comment convertir une chaîne Java en objet JSON

Cette question a été posée plus tôt, mais je ne parviens pas à comprendre l'erreur dans mon code à partir des réponses à ces questions.


J'essaie de convertir une chaîne Java en objet JSON . Voici le code:

import org.json.JSONObject;
//Other lines of code
URL seatURL = new URL("http://freemusicarchive.org/api/get/genres.json?api_key=60BLHNQCAOUFPIBZ&limit=2");
//Return the JSON Response from the API
BufferedReader br = new BufferedReader(new InputStreamReader(seatURL.openStream(),Charset.forName("UTF-8")));
String readAPIResponse = " ";
StringBuilder jsonString = new StringBuilder();
while((readAPIResponse = br.readLine()) != null){
    jsonString.append(readAPIResponse);
}
JSONObject jsonObj = new JSONObject(jsonString);
System.out.println(jsonString);
System.out.println("---------------------------");
System.out.println(jsonObj);

La sortie est:

{"title":"Free Music Archive - Genres","message":"","errors":[],"total":"163","total_pages":82,"page":1,"limit":"2","dataset":[{"genre_id":"1","genre_parent_id":"38","genre_title":"Avant-Garde","genre_handle":"Avant-Garde","genre_color":"#006666"},{"genre_id":"2","genre_parent_id":null,"genre_title":"International","genre_handle":"International","genre_color":"#CC3300"}]}
---------------------------
{}

Ainsi, comme vous pouvez le constater, la chaîne jsonstring reçoit les données, mais pas la chaîne jsonObj. J'utilise org.json JAR.

6
Nishit

Vous transmettez au constructeur JSONObject une instance d'une classe StringBuilder.

Ceci utilise le constructeur JSONObject(Object), pas celui JSONObject(String).

Votre code devrait être:

JSONObject jsonObj = new JSONObject(jsonString.toString());
16
pseudonym

@Nishit, JSONObject ne comprend pas nativement comment analyser un StringBuilder; au lieu de cela, vous semblez utiliser le constructeur JSONObject (bean Java.lang.Object) pour créer le JSONObject, bien que vous le transmettiez sous la forme d'un StringBuilder. 

Voir ce lien pour plus d'informations sur ce constructeur particulier.

http://www.json.org/javadoc/org/json/JSONObject.html#JSONObject%28Java.lang.Object%29

Lorsqu'un constructeur appelle pour une classe Java.lang.Object, il est plus que probable qu'il vous dise que vous êtes censé créer votre propre classe (puisque toutes les classes étendent finalement Java.lang.Object) et qu'il interfacera avec cette classe. de manière spécifique, bien qu’il appelle normalement une interface à la place (d’où le nom) OR, il peut accepter n’importe quelle classe et y interfacer de manière "abstraite", par exemple en appelant .toString (). En bout de ligne, vous ne pouvez généralement pas simplement passer la classe any et vous attendre à ce que cela fonctionne.

En tout cas, ce constructeur particulier s’explique comme suit:

Construire un JSONObject à partir d'un objet à l'aide de getters de bean. Il réfléchit sur toutes les méthodes publiques de l'objet. Pour chacune des méthodes sans paramètre ni nom commençant par "get" ou "is" suivi d'une lettre majuscule, la méthode est invoquée, et une clé et la valeur renvoyée par la méthode getter sont placées dans le nouveau JSONObject. La clé est formée en supprimant le préfixe "get" ou "is". Si le deuxième caractère restant n'est pas en majuscule, le premier caractère est converti en minuscule. Par exemple, si un objet a une méthode appelée "getName" et si le résultat de l'appel de object.getName () est "Larry Fine", l'objet JSON contiendra "name": "Larry Fine". 

Cela signifie donc que vous devez créer votre propre classe qui implémente les méthodes get ou is (c'est-à-dire 

public String getName() {...}

ou

public boolean isValid() {...}

Donc, pour résoudre votre problème, si vous voulez vraiment ce niveau de contrôle plus élevé et que vous voulez faire quelques manipulations (par exemple, modifier des valeurs, etc.) tout en utilisant StringBuilder pour générer dynamiquement le code, vous pouvez créer une classe qui étend le StringBuilder. afin que vous puissiez utiliser la fonctionnalité d’ajout, mais implémentez des méthodes get/is pour permettre à JSONObject d’extraire les données, mais ce n’est probablement pas ce que vous souhaitiez/avez besoin et, en fonction du JSON, vous pourriez perdre beaucoup de temps et energy créant les champs privés et les méthodes get/is (ou utilisez un IDE pour le faire à votre place) ou cela peut être totalement inutile si vous ne connaissez pas nécessairement la répartition de la chaîne JSON.

Donc, vous pouvez très simplement appeler toString() sur StringBuilder qui fournira une représentation sous forme de chaîne de l’instance StringBuilder et la transmettra au constructeur JSONObject, comme ci-dessous:

...
StringBuilder jsonString = new StringBuilder();
while((readAPIResponse = br.readLine()) != null){
    jsonString.append(readAPIResponse);
}
JSONObject jsonObj = new JSONObject(jsonString.toString());
...
2
Brooks

Conversion de la chaîne en JsonNode à l'aide d'un objet ObjectMapper:

ObjectMapper mapper = new ObjectMapper();

// For text string
JsonNode = mapper.readValue(mapper.writeValueAsString("Text-string"), JsonNode.class)

// For Array String
JsonNode = mapper.readValue("[\"Text-Array\"]"), JsonNode.class)

// For Json String 
String json = "{\"id\" : \"1\"}";
ObjectMapper mapper = new ObjectMapper();
JsonFactory factory = mapper.getFactory();
JsonParser jsonParser = factory.createParser(json);
JsonNode node = mapper.readTree(jsonParser);
1
Rahul Chauhan

La chaîne que vous passez au constructeur JSONObject doit être échappée avec quote():

public static Java.lang.String quote(Java.lang.String string)

Votre code serait maintenant:

JSONObject jsonObj = new JSONObject.quote(jsonString.toString());
System.out.println(jsonString);
System.out.println("---------------------------");
System.out.println(jsonObj);
0
Ola