2010-11-29 36 views
188

Esto podría ser una pregunta tonta, pero ¿cuál es la forma más sencilla de leer y analizar JSON de URL en Java?forma más sencilla de leer JSON desde una URL en Java

En maravilloso, es una cuestión de pocas líneas de código. Los ejemplos de Java que encuentro son ridículamente largos (y tienen un gran bloque de manejo de excepciones).

Todo lo que quiero hacer es leer el contenido de this link.

+8

El manejo de excepciones es requerido ya que Java te obliga a manejar cualquier excepción que se declare. ¿Qué pasa con el manejo de excepciones? – Falmarri

+3

bueno, la "fuerza java" es el mayor problema –

+7

Si Java no lo forzó a manejar excepciones, ¿cree que los programas seguirían ejecutándose y funcionarían bien? ¿Qué pasa si me pidieron que ingresara mi edad en un programa y le di mi opinión a snarfleblagger? ¿Debería Java permitir que el programa se ejecute sin problemas? Si no desea manejar las excepciones, entonces declare que fueron lanzadas por los métodos en los que pueden aparecer y observe cómo su programa falla cuando algo no está perfectamente bien. –

Respuesta

6

Uso HttpClient para agarrar el contenido de la URL. Y luego use la biblioteca desde json.org para analizar el JSON. He usado estas dos bibliotecas en muchos proyectos y han sido robustos y fáciles de usar.

Aparte de eso, puede intentar usar una biblioteca java API de Facebook. No tengo ninguna experiencia en esta área, pero hay una pregunta sobre el desbordamiento de pila relacionada con using a Facebook API in java. Es posible que desee mirar RestFB como una buena opción para una biblioteca.

2

No estoy seguro de si esto es eficiente, pero esta es una de las posibles maneras:

Leer JSON desde url usar url.openStream() y leer contenidos en una cadena.

construir un objeto JSON con esta cadena (más en json.org)

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

Usando el artefacto Maven org.json:json Tengo el siguiente código, que creo que es bastante corto. No tan corto como sea posible, pero aún utilizable.

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

No me di cuenta de que era tan fácil crear un flujo de entrada desde una url. –

+2

en lugar de leer carácter por carácter, puede usar readLine() en BufferedReader. Esto reducirá el número de iteraciones del ciclo while. – kunal

+6

¿Para qué? La función 'readLine' hará el ciclo, y tendré que concatenar las líneas en lugar de los caracteres, lo que es más caro. Eso no mantendría el código tan corto como lo es ahora.Además, en la notación JSON no existe el concepto de "líneas", entonces, ¿por qué debería leerlas como tal? –

56

Éstos son par de versiones alternativas con Jackson (ya que hay más de una forma que usted podría querer datos):

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); 

Y específicamente el caso habitual (OMI) en la que desea tratar con objetos Java, se puede hacer un trazador de líneas:

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

Otras bibliotecas como Gson también son compatibles con los métodos de una línea; por qué muchos ejemplos muestran secciones mucho más largas es impar. Y lo peor es que muchos ejemplos usan una biblioteca org.json obsoleta; puede haber sido lo primero, pero hay media docena de alternativas mejores, así que hay muy pocas razones para usarlo.

+0

¿Qué es la URL aquí? ¿Es una cadena u objeto de URL o byte []? – Dinesh

+0

Estaba pensando en 'java.net.URL' pero cualquiera funciona, así como muchas otras fuentes (' File', 'InputStream',' Reader', 'String'). – StaxMan

+1

Debería ser java.net.URL en el ejemplo anterior; de lo contrario, intentará analizar la cadena 'http: // ....' como json, lo que generará un error – Zotov

5

he hecho el analizador JSON en forma más sencilla, aquí 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; 

} 
} 

esta clase devuelve el objeto JSON de la url

y cuando desea que el objeto JSON que acaba de llamar esta clase y el método en su clase de actividad

mi código está aquí

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

aquí la "llave JSON" se denota que la clave en el archivo JSON

este es un ejemplo simple de archivos JSON

{ 
    "json":"hi" 
} 

aquí "json" es clave y "hi" es el valor

Esto obtendrá su valor json para el contenido de la cadena.

39

La manera más fácil: Utilice gson, la propia biblioteca goto json de google. https://code.google.com/p/google-gson/

Aquí hay un ejemplo. Voy a este sitio web de geolocalizador gratuito y analizaré el json y mostraré mi código postal. (Sólo hay que poner estas cosas en un método principal para probarlo)

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

¿Por qué obtengo el error 'NetworkOnMainThreadException'? Debo utilizar una AsyncTask o hay otra forma? En este ejemplo, ¿obtuviste este error también? – Benetz

+0

Typo, debería ser: 'rootobj.get (" zip_code "). GetAsString();' – loopasam

+0

¿Cómo importo jsonParser? Siempre sale el error: 'Error: (69, 9) Error: no se puede encontrar la clase símbolo JsonParser' – Marcel1997

23

Si no les importa usar un par de bibliotecas que se puede hacer en una sola línea.

Incluir Apache Commons IOUtils & json.org bibliotecas.

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

¿Tiene alguna adivinanza sobre por qué agregar la dependencia al gradle evitaría que esta aplicación se instale en mi Google Pixel XL? – andrdoiddev

+0

@andrdoiddev - Deberías preguntar eso como una pregunta separada. Es más general para Apache Commons, Gradle y Android Development. – ezwrighter

2

Es muy fácil, usando el jersey-cliente, basta con incluir este experto dependencia:

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

continuación, se invoca usando este ejemplo:

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

A continuación, utilice Gson de Google para analizar el JSON:

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

Nada en contra de la respuesta, pero hay tantos problemas con el paquete jersey-client ... es un desastre de errores. –

+0

no he encontrado ningún problema con él. ¿Puedes indicar algunos detalles y/o alternativas? – user3892260

+0

Terminé usando un enfoque barebone usando inputstreamreader –

Cuestiones relacionadas