Envío y análisis de objetos JSON en Android [cerrado]


137

Me gustaría enviar mensajes en forma de objetos JSON a un servidor y analizar la respuesta JSON del servidor.

Ejemplo de objeto JSON

{
  "post": {
    "username": "John Doe",
    "message": "test message",
    "image": "image url",
    "time":  "current time"
  }
}

Estoy tratando de analizar el JSON manualmente yendo atributo por atributo. ¿Hay alguna biblioteca / utilidad que pueda usar para facilitar este proceso?


2
Esa URL ya no está disponible ... ¿podría actualizarla?
Cipi

1
Aquí hay un ejemplo detallado: Android - Ejemplo de análisis JSON
Paresh Mayani

1
@ Paresh Mayani y @ primpap .. Sé que podemos poblar datos del servidor usando JSON recibido del servidor usando el método get, me siento cómodo con eso ... pero si usamos el método post para enviar los datos al servidor, hagamos enviamos los datos como JSON nuevamente, me refiero a la cita de la pregunta primpap "Me gustaría enviar mensajes en forma de objetos JSON a un servidor Django" ..... Estoy usando Mysql en el servidor ... o ¿Envío un objeto JSON? ... puede aclararme esta información ... o cualquier enlace que me ayude a entender el concepto será útil, gracias
Devrath

Respuestas:


118

Me sorprende que no se hayan mencionado: pero en lugar de utilizar el proceso básico en lugar del manual con el pequeño paquete de json.org, GSon y Jackson son mucho más cómodos de usar. Entonces:

Por lo tanto, puede vincularse a sus propios POJO, no a algunos nodos de árbol a medias o Listas y mapas. (y al menos Jackson permite la vinculación a tales cosas también (quizás GSON también, no estoy seguro), JsonNode, Map, List, si realmente quiere estos en lugar de objetos 'reales')

EDITAR 19-MAR-2014:

Otro nuevo contendiente es la biblioteca Jackson jr : utiliza el mismo analizador / generador de Streaming rápido que Jackson ( jackson-core), pero la parte de enlace de datos es pequeña (50kB). La funcionalidad es más limitada (sin anotaciones, solo Java Beans normales), pero el rendimiento en cuanto a rendimiento debería ser rápido, y la sobrecarga de inicialización (primera llamada) también muy baja. Por lo tanto, podría ser una buena opción, especialmente para aplicaciones más pequeñas.


10
+1 para GSON. Hemos utilizado especialmente los sitios de soporte de transmisión de GSON. Google.com/site/gson/streaming en nuestras aplicaciones de Android.
Andre Steingress

FWIW, Jackson también tiene API de transmisión: wiki.fasterxml.com/JacksonStreamingApi
StaxMan

2
También +1 para transmisión GSON. Al principio se implementó la transmisión de Jackson, pero aunque era funcional en la versión de depuración, ProGuard generó toneladas de errores y la versión de lanzamiento provoca bloqueos que son difíciles de rastrear. Estoy seguro de que este no es un problema relacionado con Jackson, pero me hizo cambiar a GSON, que funcionó bien y solo requirió 14kB adicionales para la transmisión.
sven

¿Y para estúpidos e impredecibles json mezclando cadenas y listas ej .: ["toto", "tata", ["monty", ["tor", "python"]]]? (tipo de estructura de datos que requiere funciones recursivas para consumirlo)
christophe31

85

Puede usar org.json.JSONObject y org.json.JSONTokener . no necesita ninguna biblioteca externa ya que estas clases vienen con Android SDK


¡Uy! Me lo perdí. De hecho, son las bibliotecas org.json en el sitio web.
Gaurav Vaish

Esto es lo que uso, y funciona a las mil maravillas.
Adam

Sería genial si se pudiera dar un ejemplo o un enlace al mismo. Es más fácil aprender de esa manera. :)
Primal Pappachan


1
Mucho más comodidad, menos código para escribir: una o dos líneas en lugar de docenas.
StaxMan

31

GSON es más fácil de usar y el camino a seguir si los datos tienen una estructura definida.

Descargar gson .

Agréguelo a las bibliotecas referenciadas.

package com.tut.JSON;

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

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class SimpleJson extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        String jString = "{\"username\": \"tom\", \"message\": \"roger that\"}  ";


        GsonBuilder gsonb = new GsonBuilder();
        Gson gson = gsonb.create();
        Post pst;

        try {
            pst = gson.fromJson(jString,  Post.class);

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

Código para la clase Post

package com.tut.JSON;

public class Post {

    String message;
    String time;
    String username;
    Bitmap icon;
}

44
Por lo que vale, el código puede simplificarse: que la conversión de JSONObject es innecesaria. Y los setters y getters son opcionales para GSon; se puede agregar si se quiere, pero no es estrictamente necesario.
StaxMan

44
Solo para aclarar el comentario de StaxMan. Su ejemplo es tomar jString, convertirlo en un JSONObject, luego convertirlo nuevamente en una Cadena para que el gson lo lea. Simplemente use pst = gson.fromJson (jString, Post.class). Creo que esto también eliminará la necesidad de try-catch. Y como StaxMan también señala, los establecedores y captadores en la clase Post.no agregan ningún valor. Sería útil para otros corregir su ejemplo.
Matt


4

Esta es la clase JsonParser

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");
            }
            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());
        }

        // return JSON String
        return jObj;

    }

Nota: DefaultHttpClient ya no es compatible con sdk 23, por lo que es aconsejable usar target sdk 21 con este código.


3

Realmente no hay nada para JSON. Los corchetes son para "objetos" (matrices asociativas) y los corchetes son para matrices sin claves (indexadas numéricamente). En cuanto a trabajar con él en Android, hay clases preparadas para eso incluidas en el SDK (no se requiere descarga).

Echa un vistazo a estas clases: http://developer.android.com/reference/org/json/package-summary.html


¡Supongo que querías decir llaves y no llaves angulares!
Gaurav Vaish

2

Otras respuestas han señalado a Jackson y GSON, las populares bibliotecas JSON adicionales para Android, y json.org, el paquete JSON básico que se incluye en Android.

Pero creo que también vale la pena señalar que Android ahora tiene su propia API JSON con todas las funciones.

Esto se agregó en Honeycomb: API nivel 11.

Esto comprende
- android.util.JsonReader: docs , y source
- android.util.JsonWriter: docs , y source

También agregaré una consideración adicional que me empuja hacia Jackson y GSON: he encontrado útil utilizar bibliotecas de terceros en lugar de paquetes de Android. * Porque el código que escribo puede compartirse entre el cliente y el servidor. Esto es particularmente relevante para algo como JSON, donde es posible que desee serializar datos a JSON en un extremo para enviarlos al otro extremo. Para casos de uso como ese, si usa Java en ambos extremos, ayuda a evitar la introducción de dependencias de Android. *.

O supongo que uno podría tomar el código fuente de Android. * Relevante y agregarlo a su proyecto de servidor, pero no lo he intentado ...



1

solo necesitas importar esto

   import org.json.JSONObject;


  constructing the String that you want to send

 JSONObject param=new JSONObject();
 JSONObject post=new JSONObject();

estoy usando dos objetos porque puedes tener un jsonObject dentro de otro

post.put("username(here i write the key)","someusername"(here i put the value);
post.put("message","this is a sweet message");
post.put("image","http://localhost/someimage.jpg");
post.put("time":  "present time");

luego puse la publicación json dentro de otra como esta

  param.put("post",post);

este es el método que uso para hacer una solicitud

 makeRequest(param.toString());

public JSONObject makeRequest(String param)
{
    try
    {

establecer la conexión

        urlConnection = new URL("your url");
        connection = (HttpURLConnection) urlConnection.openConnection();
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-type", "application/json;charset=UTF-8");
        connection.setReadTimeout(60000);
        connection.setConnectTimeout(60000);
        connection.connect();

establecer el flujo de salida

        dataOutputStream = new DataOutputStream(connection.getOutputStream());

Lo uso para ver en el logcat lo que estoy enviando

        Log.d("OUTPUT STREAM  " ,param);
        dataOutputStream.writeBytes(param);
        dataOutputStream.flush();
        dataOutputStream.close();

        InputStream in = new BufferedInputStream(connection.getInputStream());
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        result = new StringBuilder();
        String line;

aquí se construye la cuerda

        while ((line = reader.readLine()) != null)
        {
            result.append(line);
        }

uso este registro para ver qué viene en la respuesta

         Log.d("INPUTSTREAM: ",result.toString());

Instanciar un JSON con la cadena que contiene la respuesta del servidor

        jResponse=new JSONObject(result.toString());

    }
    catch (IOException e) {
        e.printStackTrace();
        return jResponse=null;
    } catch (JSONException e)
    {
        e.printStackTrace();
        return jResponse=null;
    }
    connection.disconnect();
    return jResponse;
}

Gracias por su tiempo de antemano. Uso su código para enviar cadenas codificadas en base64 al servidor django, pero cuando hago clic en el botón para enviar al servidor, la aplicación se bloquea. ¿Podrías ayudarme a abordar esto?
Noman marwat

0

si está buscando un análisis rápido de json en Android, le sugiero una herramienta que está disponible gratuitamente.

Herramienta JSON Class Creator

Es de uso gratuito y crea su clase de análisis de todos los json en uno o dos segundos ...: D


0

Aunque los usuarios ya proporcionan respuestas excelentes, como fomentar el uso de GSON, etc., me gustaría sugerir el uso de org.json . Incluye la mayoría de las funcionalidades de GSON. También le permite pasar una cadena json como argumento a su JSONObject y se encargará del resto, por ejemplo:

JSONObject json = new JSONObject("some random json string");

Esta funcionalidad lo convierte en mi favorito personal.


0

Existen diferentes bibliotecas de código abierto, que puede usar para analizar json.

org.json: - Si desea leer o escribir json, puede usar esta biblioteca. Primero cree JsonObject: -

JSONObject jsonObj = new JSONObject(<jsonStr>);

Ahora, use este objeto para obtener sus valores: -

String id = jsonObj.getString("id");

Puedes ver el ejemplo completo aquí

Jackson databind: - Si desea vincular y analizar su json a una clase POJO particular, puede usar la biblioteca jackson-databind, esto vinculará su json a la clase POJO: -

ObjectMapper mapper = new ObjectMapper();
post= mapper.readValue(json, Post.class);

Puedes ver el ejemplo completo aquí

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.