Invio e analisi di oggetti JSON in Android [chiuso]


137

Vorrei inviare messaggi sotto forma di oggetti JSON a un server e analizzare la risposta JSON dal server.

Esempio di oggetto JSON

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

Sto cercando di analizzare manualmente JSON andando attributo per attributo. C'è qualche libreria / utility che posso usare per semplificare questo processo?


2
Quell'URL non è più disponibile ... potresti aggiornarlo?
Cipi,

1
Ecco un esempio dettagliato: Android - Esempio di analisi JSON
Paresh Mayani,

1
@ Paresh Mayani & @ primpap .. So che possiamo popolare i dati dal server usando JSON ricevuto dal server usando il metodo get, mi sento a mio agio con esso .... ma se usiamo il metodo post per inviare i dati al server, facciamo inviamo nuovamente i dati come JSON, mi riferisco alla citazione della domanda primpap "Vorrei inviare messaggi sotto forma di oggetti JSON a un server Django" ..... Sto usando Mysql sul server .... o Mando l'oggetto JSON? ... puoi chiarirmi queste informazioni .... o qualsiasi link che mi aiuti a capire il concetto sarà utile, grazie
Devrath

Risposte:


118

Sono sorpreso che questi non siano stati menzionati: ma invece di usare un processo piuttosto semplice con il piccolo pacchetto di json.org, GSon e Jackson sono molto più convenienti da usare. Così:

Quindi puoi effettivamente associarti ai tuoi POJO, non ad alcuni nodi di alberi semi-compilati o Elenchi e mappe. (e almeno Jackson permette di legare anche a queste cose (forse anche GSON, non sono sicuro), JsonNode, Map, List, se vuoi davvero questi invece di oggetti "reali")

MODIFICA 19-MAR-2014:

Un altro nuovo concorrente è la libreria Jackson jr : utilizza lo stesso parser / generatore di streaming veloce di Jackson ( jackson-core), ma la parte di associazione dei dati è minuscola (50kB). La funzionalità è più limitata (nessuna annotazione, solo normali bean Java), ma le prestazioni dovrebbero essere veloci e anche l'inizializzazione (prima chiamata) molto bassa. Quindi potrebbe essere una buona scelta, soprattutto per le app più piccole.


10
+1 per GSON. Abbiamo utilizzato soprattutto il supporto di streaming di GSON sites.google.com/site/gson/streaming nelle nostre applicazioni Android.
Andre Steingress,

FWIW, Jackson ha anche API di streaming: wiki.fasterxml.com/JacksonStreamingApi
StaxMan

2
Inoltre +1 per lo streaming GSON. Implementato inizialmente lo streaming Jackson ma sebbene funzionante nella versione di debug, ProGuard ha generato tonnellate di errori e la versione di rilascio provoca arresti anomali difficili da rintracciare. Sono sicuro che questo non è un problema relativo a Jackson, ma mi ha fatto passare a GSON che ha funzionato bene e ha richiesto solo 14kB aggiuntivi solo per lo streaming.
sabato

E per stupido imprevedibile json che mescola stringa ed elenchi ex: ["toto", "tata", ["monty", ["tor", "python"]]]? (tipo di struttura di dati che richiede funzioni ricorsive per consumarlo)
christophe31

85

Puoi usare org.json.JSONObject e org.json.JSONTokener . non hai bisogno di alcuna libreria esterna poiché queste classi vengono fornite con Android SDK


Oops! Ho perso questo. Infatti, sono le librerie org.json sul sito Web.
Gaurav Vaish,

Questo è quello che uso e funziona come un fascino.
Adamo,

Sarebbe bello se si potesse dare un esempio o un collegamento allo stesso. È più facile da imparare in quel modo. :)
Primal Pappachan,


1
Molto più convenienza, meno codice da scrivere: una o due righe invece di dozzine.
StaxMan,

31

GSON è il più facile da usare e la strada da percorrere se i dati hanno una struttura definita.

Scarica gson .

Aggiungilo alle librerie referenziate.

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

Codice per la classe Post

package com.tut.JSON;

public class Post {

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

4
Per quello che vale, il codice può essere semplificato: la conversione JSONObject non è necessaria. E setter e getter sono opzionali per GSon; può essere aggiunto se si desidera, ma non strettamente necessario.
StaxMan,

4
Giusto per chiarire il commento di StaxMan. Il tuo esempio è prendere jString, convertirlo in un oggetto JSONOb, quindi convertirlo nuovamente in una stringa per la lettura di gson. Usa semplicemente pst = gson.fromJson (jString, Post.class). Credo che questo eliminerà anche la necessità di provare a catturare. E come sottolinea anche StaxMan, i setter e i getter in Post.class non aggiungono alcun valore. Sarebbe utile per gli altri correggere il tuo esempio.
Matt,

Ho rimosso la parte a doppia conversione dalla risposta
whlk

4

Questa è la classe 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 non è più supportato da SDK 23, quindi è consigliabile utilizzare Target SDK 21 con questo codice.


3

Non c'è davvero nulla in JSON. Le parentesi graffe sono per "oggetti" (matrici associative) e le parentesi quadre sono per matrici senza chiavi (indicizzate numericamente). Per quanto riguarda lavorare con esso in Android, ci sono classi già pronte per quelle incluse in sdk (nessun download richiesto).

Dai un'occhiata a queste classi: http://developer.android.com/reference/org/json/package-summary.html


Suppongo che intendevi parentesi graffe e non parentesi angolari!
Gaurav Vaish,

2

Altre risposte hanno notato Jackson e GSON - le famose librerie JSON aggiuntive per Android e json.org, il pacchetto JSON bare-bones che è incluso in Android.

Ma penso che valga anche la pena notare che Android ora ha la sua API JSON con funzionalità complete.

Questo è stato aggiunto in Honeycomb: API level 11.

Questo comprende
- android.util.JsonReader: docs e source
- android.util.JsonWriter: docs e source

Aggiungerò anche un'ulteriore considerazione che mi spinge di nuovo verso Jackson e GSON: ho trovato utile usare librerie di terze parti piuttosto che pacchetti Android. * Perché il codice che scrivo può essere condiviso tra client e server. Ciò è particolarmente rilevante per qualcosa come JSON, in cui potresti voler serializzare i dati su JSON da un lato per l'invio dall'altro. Per casi come questo, se usi Java su entrambe le estremità aiuta a evitare di introdurre dipendenze android. *.

O immagino che si potrebbe prendere il codice sorgente Android. * Rilevante e aggiungerlo al progetto del server, ma non l'ho provato ...



1

devi solo importare questo

   import org.json.JSONObject;


  constructing the String that you want to send

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

sto usando due oggetti perché puoi avere un jsonObject all'interno di un altro

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

poi ho inserito il post json in un altro come questo

  param.put("post",post);

questo è il metodo che uso per fare una richiesta

 makeRequest(param.toString());

public JSONObject makeRequest(String param)
{
    try
    {

impostazione della connessione

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

impostazione dell'outputstream

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

lo uso per vedere nel logcat ciò che sto inviando

        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;

qui viene costruita la stringa

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

io uso questo registro per vedere cosa sta arrivando nella risposta

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

istanza di un json con la stringa che contiene la risposta del server

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

grazie per il tuo tempo in anticipo. Uso il tuo codice per inviare una stringa codificata in base64 al server django ma quando faccio clic sul pulsante per inviare al server, l'APP si blocca. Potresti aiutarmi come affrontare questo?
Noman marwat,

0

se stai cercando un analisi json veloce in Android di quanto ti suggerisca uno strumento che è liberamente disponibile.

Strumento JSON Class Creator

È gratuito e crea la tua classe di analisi all json in uno-due secondi ..: D


0

Sebbene ci siano già ottime risposte fornite dagli utenti come l'uso incoraggiante di GSON ecc. Vorrei suggerire l'uso di org.json . Include la maggior parte delle funzionalità GSON. Ti consente anche di passare la stringa JSON come argomento al suo JSONObject e si occuperà del riposo, ad esempio:

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

Questa funzionalità lo rende il mio preferito personale.


0

Esistono diverse librerie open source, che è possibile utilizzare per l'analisi di json.

org.json: - Se vuoi leggere o scrivere json, puoi usare questa libreria. Per prima cosa crea JsonObject: -

JSONObject jsonObj = new JSONObject(<jsonStr>);

Ora, usa questo oggetto per ottenere i tuoi valori: -

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

Puoi vedere l'esempio completo qui

Jackson databind: - Se si desidera associare e analizzare il proprio json a una particolare classe POJO, è possibile utilizzare la libreria jackson-databind, ciò legherà il proprio json alla classe POJO: -

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

Puoi vedere l'esempio completo qui

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.