2010-11-29 15 views
188

Cela pourrait être une question stupide, mais quelle est la façon la plus simple à lire et à analyser JSON de URL dans Java?façon la plus simple de lire JSON à partir d'une URL en java

Dans Groovy, il s'agit de quelques lignes de code. Les exemples Java que je trouve sont ridiculement longs (et ont un énorme bloc de gestion des exceptions). Je veux juste lire le contenu de this link.

+8

La gestion des exceptions est requis car Java vous oblige à gérer les exceptions qui sont déclarées. Quel est le problème avec la gestion des exceptions? – Falmarri

+3

bien, le "java force vous" est le plus gros problème –

+7

Si java ne vous forçait pas à gérer les exceptions, pensez-vous que les programmes fonctionneraient toujours bien? Et si on me demandait d'entrer mon âge dans un programme et que je donnais snarfleblagger comme contribution? Java devrait-il permettre au programme de s'exécuter sans problèmes? Si vous ne voulez pas gérer les exceptions, déclarez-les comme étant lancées par les méthodes dans lesquelles elles peuvent apparaître et regardez votre programme échouer lorsque quelque chose ne va pas parfaitement. –

Répondre

6

Utilisez HttpClient pour récupérer le contenu de l'URL. Et puis utilisez la bibliothèque de json.org pour analyser le JSON. J'ai utilisé ces deux bibliothèques sur de nombreux projets et elles ont été robustes et simples à utiliser. En plus de cela, vous pouvez essayer d'utiliser une bibliothèque Java API Facebook. Je n'ai aucune expérience dans ce domaine, mais il y a une question sur le débordement de pile liée à using a Facebook API in java. Vous voudrez peut-être regarder RestFB comme un bon choix pour une bibliothèque à utiliser.

2

Je ne sais pas si cela est efficace, mais c'est l'une des façons possibles:

Lire JSON url utiliser url.openStream() et lire le contenu dans une chaîne.

construire un objet JSON avec cette chaîne (plus à json.org)

JSONObject(java.lang.String source) 
     Construct a JSONObject from a source JSON text string. 
160

Utilisation de l'artefact Maven org.json:json Je suis le code suivant, que je pense est assez courte. Pas aussi court que possible, mais toujours utilisable.

package so4308554; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.Reader; 
import java.net.URL; 
import java.nio.charset.Charset; 

import org.json.JSONException; 
import org.json.JSONObject; 

public class JsonReader { 

    private static String readAll(Reader rd) throws IOException { 
    StringBuilder sb = new StringBuilder(); 
    int cp; 
    while ((cp = rd.read()) != -1) { 
     sb.append((char) cp); 
    } 
    return sb.toString(); 
    } 

    public static JSONObject readJsonFromUrl(String url) throws IOException, JSONException { 
    InputStream is = new URL(url).openStream(); 
    try { 
     BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); 
     String jsonText = readAll(rd); 
     JSONObject json = new JSONObject(jsonText); 
     return json; 
    } finally { 
     is.close(); 
    } 
    } 

    public static void main(String[] args) throws IOException, JSONException { 
    JSONObject json = readJsonFromUrl("https://graph.facebook.com/19292868552"); 
    System.out.println(json.toString()); 
    System.out.println(json.get("id")); 
    } 
} 
+0

Je ne savais pas que c'était facile de créer un flux d'entrée à partir d'une URL. –

+2

au lieu de lire caractère par caractère, vous pouvez utiliser readLine() sur BufferedReader. Cela réduira le nombre d'itérations de la boucle while. – kunal

+6

Pour quoi faire? La fonction 'readLine' fera alors la boucle, et je dois concaténer les lignes au lieu des caractères, ce qui est plus cher. Cela ne garderait pas le code aussi court qu'il est maintenant.De plus, en notation JSON, il n'y a pas de notion de "lignes", alors pourquoi devrais-je les lire en tant que telles? –

56

Voici quelques alternatives versions avec Jackson (car il y a plus d'une façon, vous voudrez peut-être données):

ObjectMapper mapper = new ObjectMapper(); // just need one 
    // Got a Java class that data maps to nicely? If so: 
    FacebookGraph graph = mapper.readValue(url, FaceBookGraph.class); 
    // Or: if no class (and don't need one), just map to Map.class: 
    Map<String,Object> map = mapper.readValue(url, Map.class); 

Et plus particulièrement le cas habituel (OMI) où vous voulez traiter avec des objets Java, peut être réalisé en une seule ligne:

FacebookGraph graph = new ObjectMapper().readValue(url, FaceBookGraph.class); 

D'autres bibliothèques comme Gson prennent également en charge les méthodes d'une ligne; pourquoi de nombreux exemples montrent des sections beaucoup plus longues est étrange. Et pire encore, de nombreux exemples utilisent une bibliothèque org.json obsolète; C'est peut-être la première chose à faire, mais il y a une demi-douzaine de meilleures alternatives, donc il y a très peu de raisons de l'utiliser.

+0

Qu'est-ce que l'URL ici? Est-ce une chaîne ou un objet URL ou un octet []? – Dinesh

+0

Je pensais à 'java.net.URL' mais l'un fonctionne, ainsi que plein d'autres sources (' File', 'InputStream',' Reader', 'String'). – StaxMan

+1

Il devrait être java.net.URL dans l'exemple ci-dessus, sinon il essayera d'analyser la chaîne 'http: // ....' comme un json, ce qui donnera une erreur – Zotov

5

Je l'ai fait l'analyseur JSON de manière plus simple, ici il est

package com.inzane.shoapp.activity; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.UnsupportedEncodingException; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.json.JSONException; 
import org.json.JSONObject; 

import android.util.Log; 

public class JSONParser { 

static InputStream is = null; 
static JSONObject jObj = null; 
static String json = ""; 

// constructor 
public JSONParser() { 

} 

public JSONObject getJSONFromUrl(String url) { 

    // Making HTTP request 
    try { 
     // defaultHttpClient 
     DefaultHttpClient httpClient = new DefaultHttpClient(); 
     HttpPost httpPost = new HttpPost(url); 

     HttpResponse httpResponse = httpClient.execute(httpPost); 
     HttpEntity httpEntity = httpResponse.getEntity(); 
     is = httpEntity.getContent(); 

    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } catch (ClientProtocolException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    try { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(
       is, "iso-8859-1"), 8); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     while ((line = reader.readLine()) != null) { 
      sb.append(line + "\n"); 
      System.out.println(line); 
     } 
     is.close(); 
     json = sb.toString(); 

    } catch (Exception e) { 
     Log.e("Buffer Error", "Error converting result " + e.toString()); 
    } 

    // try parse the string to a JSON object 
    try { 
     jObj = new JSONObject(json); 
    } catch (JSONException e) { 
     Log.e("JSON Parser", "Error parsing data " + e.toString()); 
     System.out.println("error on parse data in jsonparser.java"); 
    } 

    // return JSON String 
    return jObj; 

} 
} 

cette classe renvoie l'objet JSON de l'url

et quand vous voulez l'objet JSON vous appelez simplement cette classe et la méthode dans votre classe d'activité

mon code est ici

String url = "your url"; 
JSONParser jsonParser = new JSONParser(); 
JSONObject object = jsonParser.getJSONFromUrl(url); 
String content=object.getString("json key"); 

ici la « clé JSON » est noté que la clé dans votre fichier JSON

c'est un simple exemple de fichier JSON

{ 
    "json":"hi" 
} 

Ici « JSON » est la clé et « salut » est la valeur

Cela obtiendra votre valeur json au contenu de chaîne.

39

La méthode la plus simple: Utilisez gson, la bibliothèque goto json de google. https://code.google.com/p/google-gson/

Voici un exemple. Je vais sur ce site web de géolocalisation gratuit et j'examine le fichier json et affiche mon code postal. (Il suffit de mettre ce genre de choses dans une méthode principale pour le tester)

String sURL = "http://freegeoip.net/json/"; //just a string 

    // Connect to the URL using java's native library 
    URL url = new URL(sURL); 
    HttpURLConnection request = (HttpURLConnection) url.openConnection(); 
    request.connect(); 

    // Convert to a JSON object to print data 
    JsonParser jp = new JsonParser(); //from gson 
    JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element 
    JsonObject rootobj = root.getAsJsonObject(); //May be an array, may be an object. 
    zipcode = rootobj.get("zip_code").getAsString(); //just grab the zipcode 
+0

Pourquoi j'obtiens l'erreur 'NetworkOnMainThreadException'? Je dois utiliser un AsyncTask ou il y a un autre moyen? Dans cet exemple, avez-vous eu cette erreur aussi? – Benetz

+0

Typo, devrait être: 'rootobj.get (" zip_code "). GetAsString();' – loopasam

+0

Comment importer le jsonParser? Je reçois toujours l'erreur: 'Erreur: (69, 9) Erreur: ne peut pas trouver la classe symbole JsonParser' – Marcel1997

23

Si vous ne me dérange pas en utilisant une bibliothèque couple, il peut être fait en une seule ligne.

Inclure Apache Commons IOUtils & json.org bibliothèques.

JSONObject json = new JSONObject(IOUtils.toString(new URL("https://graph.facebook.com/me"), Charset.forName("UTF-8"))); 
+0

Avez-vous une idée de la raison pour laquelle l'ajout de la dépendance au Gradle empêcherait l'installation de cette application sur mon Google Pixel XL? – andrdoiddev

+0

@andrdoiddev - Vous devriez poser cette question séparément. Il est plus général à Apache Commons, Gradle et Android Development. – ezwrighter

2

Il est très facile, en utilisant jersey client, il suffit d'inclure cette dépendance Maven:

<dependency> 
    <groupId>org.glassfish.jersey.core</groupId> 
    <artifactId>jersey-client</artifactId> 
    <version>2.25.1</version> 
</dependency> 

ensuite invoquer à l'aide de cet exemple:

String json = ClientBuilder.newClient().target("http://api.coindesk.com/v1/bpi/currentprice.json").request().accept(MediaType.APPLICATION_JSON).get(String.class); 

Utilisez ensuite Gson de Google pour analyser la JSON:

Gson gson = new Gson(); 
Type gm = new TypeToken<CoinDeskMessage>() {}.getType(); 
CoinDeskMessage cdm = gson.fromJson(json, gm); 
+0

Rien contre la réponse, mais tant de problèmes avec le paquet jersey-client ... c'est un tas d'erreurs. –

+0

Je n'ai rencontré aucun problème avec cela. pouvez-vous indiquer quelques détails et/ou alternatives? – user3892260

+0

J'ai fini par utiliser une approche barebone utilisant entréestreamreader –