web-dev-qa-db-fra.com

Utilisation de base de JSONPath dans Java

J'ai JSON comme chaîne et un JSONPath comme chaîne. Je voudrais interroger le JSON avec le chemin JSON, obtenir le JSON résultant sous forme de chaîne.

Je suppose que json-path de Jaywayest la norme . Le API en ligne , cependant, n'a pas beaucoup de relation avec le bibliothèque réelle que vous obtenez de Maven . version de GrepCode correspond à peu près cependant.

Il semble que je devrais pouvoir faire:

String originalJson; //these are initialized to actual data
String jsonPath;
String queriedJson = JsonPath.<String>read(originalJson, jsonPath);

Le problème est que read retourne tout ce qui lui semble le plus approprié en fonction de ce que JSONPath trouve réellement (par exemple un List<Object>, String, double, etc.), donc mon code lève une exception pour certaines requêtes. Il semble assez raisonnable de supposer qu'il y aurait un moyen d'interroger JSON et de récupérer JSON; Aucune suggestion?

18
akroy

Il existe certainement un moyen d'interroger Json et de récupérer Json à l'aide de JsonPath. Voir l'exemple ci-dessous:

 String jsonString = "{\"delivery_codes\": [{\"postal_code\": {\"district\": \"Ghaziabad\", \"pin\": 201001, \"pre_paid\": \"Y\", \"cash\": \"Y\", \"pickup\": \"Y\", \"repl\": \"N\", \"cod\": \"Y\", \"is_oda\": \"N\", \"sort_code\": \"GB\", \"state_code\": \"UP\"}}]}";
 String jsonExp = "$.delivery_codes";
 JsonNode pincodes = JsonPath.read(jsonExp, jsonString, JsonNode.class);
 System.out.println("pincodesJson : "+pincodes);

La sortie de ce qui précède sera Json interne.

[{"postal_code": {"district": "Ghaziabad", "pin": 201001, "pre_paid": "Y", "cash": "Y", "pickup": "Y", "repl": " N "," cod ":" Y "," is_oda ":" N "," sort_code ":" GB "," state_code ":" UP "}}]]

Maintenant, chaque paire nom/valeur individuelle peut être analysée en itérant la liste (JsonNode) ci-dessus.

for(int i = 0; i< pincodes.size();i++){
    JsonNode node = pincodes.get(i);
    String pin = JsonPath.read("$.postal_code.pin", node, String.class);
    String district = JsonPath.read("$.postal_code.district", node, String.class);
    System.out.println("pin :: " + pin + " district :: " + district );
}

La sortie sera:

pin :: 201001 district :: Ghaziabad

Selon le Json que vous essayez d'analyser, vous pouvez décider de récupérer une liste ou simplement une seule valeur String/Long.

J'espère que cela vous aidera à résoudre votre problème.

11
Ankur Choudhary

L'API Java JsonPath trouvée à jayway JsonPath pourrait avoir changé un peu depuis toutes les réponses/commentaires ci-dessus. Documentation aussi. Suivez simplement le lien ci-dessus et lisez que README.md , il contient une documentation d'utilisation IMO très claire.

Fondamentalement, à partir de la dernière version 2.2.0 de la bibliothèque, il existe différentes façons de réaliser ce qui a été demandé ici, telles que:

Pattern:
--------
String json = "{...your JSON here...}";
String jsonPathExpression = "$...your jsonPath expression here..."; 
J requestedClass = JsonPath.parse(json).read(jsonPathExpression, YouRequestedClass.class);

Example:
--------
// For better readability:  {"store": { "books": [ {"author": "Stephen King", "title": "IT"}, {"author": "Agatha Christie", "title": "The ABC Murders"} ] } }
String json = "{\"store\": { \"books\": [ {\"author\": \"Stephen King\", \"title\": \"IT\"}, {\"author\": \"Agatha Christie\", \"title\": \"The ABC Murders\"} ] } }";
String jsonPathExpression = "$.store.books[?(@.title=='IT')]"; 
JsonNode jsonNode = JsonPath.parse(json).read(jsonPathExpression, JsonNode.class);

Et pour référence, appeler 'JsonPath.parse (..)' retournera un objet de classe ' JsonContent ' implémentant certaines interfaces telles que ' ReadContext ', qui contient plusieurs différents Opérations 'read (..)', comme celle illustrée ci-dessus:

/**
 * Reads the given path from this context
 *
 * @param path path to apply
 * @param type    expected return type (will try to map)
 * @param <T>
 * @return result
 */
<T> T read(JsonPath path, Class<T> type);

J'espère que cela aidera n'importe qui.

7
francois

Pour ceux d'entre vous qui se demandent pourquoi certaines de ces réponses vieilles de plusieurs années ne fonctionnent pas, vous pouvez apprendre beaucoup des cas de test .

En septembre 2018, voici comment obtenir les résultats de Jackson JsonNode:

Configuration jacksonConfig = Configuration.builder()
                              .mappingProvider( new JacksonMappingProvider() )
                              .jsonProvider( new JacksonJsonProvider() )
                              .build();

JsonNode node = JsonPath.using( jacksonConfig ).parse(jsonString);
1
Hoobajoob