Autore Topic: Parsing JSON con più di un elemento  (Letto 1030 volte)

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Parsing JSON con più di un elemento
« il: 20 Marzo 2015, 11:34:08 CET »
0
Salve a tutti!

Sto cercando di creare che faccia una richiesta http ad un php online, riceva il json , ne faccia il parsing e lo inserisce dentro a delle variabili che userò per creare delle liste.

Va tutto bene finché ho un solo json di cui fare il parsing, quando ne ho più di uno non so come fare.

Questo è il codice della "main activity" che uso:
Codice (Java): [Seleziona]
  protected class GetInfo extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {

            JSONObject jobj = null;
            ClientServerInterface clientServerInterface = new ClientServerInterface();
            String  ab="";

            String url = ("http://mylink/geteventi.php");


                    try {
                       ab = jobj.getString("nome");
                    } catch (JSONException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }


            return null;
        }
    }

mentre questa è la classe che fa tutto il lavoro di richiesta http e parsing:
Codice (Java): [Seleziona]
/* this class helps to get data from server*/
public class ClientServerInterface {
    //input stream deals with bytes
    static InputStream is = null;
    static JSONObject jobj = null;
    static String json = "";
    //constructor
    public ClientServerInterface(){

    }
    //this method returns json object.
    public JSONObject makeHttpRequest(String url){
//http client helps to send and receive data
        DefaultHttpClient httpclient = new DefaultHttpClient();
//our request method is post
        HttpPost httppost = new HttpPost(url);
        try {
//get the response
            HttpResponse httpresponse = httpclient.execute(httppost);
            HttpEntity httpentity = httpresponse.getEntity();
// get the content and store it into inputstream object.
            is = httpentity.getContent();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        try {
//convert byte-stream to character-stream.
            BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            try {
                while((line = reader.readLine())!=null){
                    sb.append(line+"\n");

                }
//close the input stream
                is.close();
                json = sb.toString();
                try {
                    jobj = new JSONObject(json);
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return jobj;
    }
}

mentre questo è ciò che ottengo dal php:

{"ID":"4","nome":"ye","descrizione":"gtsthrd","paese":"hstrhyr","indirizzo":"","inizio":"thsrhyrd","fine":"","nomeimg":"urzano.png"}{"ID":"3","nome":"htr","descrizione":"htds","paese":"hts","indirizzo":"","inizio":"htsr","fine":"","nomeimg":""}

naturalmente ottengo solo quello con ID=4 con il codice di ora, come faccio ad ottenere anche il resto?

Offline LinkOut

  • Utente normale
  • ***
  • Post: 269
  • Respect: +37
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:Parsing JSON con più di un elemento
« Risposta #1 il: 20 Marzo 2015, 12:29:00 CET »
0
Per renderti la vita più facile e parserizzare JSON in automatico ti consiglio Jackson oppure Gson..

Impara questi, perchè quando ti ritroverai a dover parserizzare JSON complessi, voglio poi vederti a farlo a mano :P

Per me quello che tu hai in output è sbagliato, perchè dovresti avere un array di oggetti... quindi il JSON dovrebbe iniziare con una "["

Es. [{oggetto},{oggetto}]

Quindi serializzarlo è semplice perchè diventa appunto un array di oggetti.


Saluti.

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Parsing JSON con più di un elemento
« Risposta #2 il: 20 Marzo 2015, 13:22:10 CET »
0
Ok ho cambiato il php ed ora ottengo questo:
{"eventi":[{"ID":"4","nome":"ye","descrizione":"gtsthrd","paese":"hstrhyr","indirizzo":"","inizio":"thsrhyrd","fine":"","nomeimg":"urzano.png"},{"ID":"3","nome":"htr","descrizione":"htds","paese":"hts","indirizzo":"","inizio":"htsr","fine":"","nomeimg":""}]}

ho cambiato anche il codice java in questo modo:
Codice (Java): [Seleziona]
  String result = "";
            String stringaFinale = "";
            InputStream is = null;

            //http post
            try{
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost("http://mylink/geteventi.php");
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();

                is = entity.getContent();

                Log.i("test", response.toString());
                Log.i("test2",is.toString());


            }catch(Exception e){
                Log.e("TEST", "Errore nella connessione http "+e.toString());
            }
            if(is != null){
                //converto la risposta in stringa
                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();

                    result=sb.toString();
                    System.out.println(result.length());
                }catch(Exception e){
                    Log.e("TEST", "Errore nel convertire il risultato "+e.toString());
                }
                System.out.println(result);

                if((!result.isEmpty())&&(result.length()>5)){
                    //parsing dei dati arrivati in formato json
                    try{
                        Log.i("test", "entrato");
                        JSONArray jArray = new JSONArray(result);
                        for(int i=0;i<jArray.length();i++){
                            JSONObject json_data = jArray.getJSONObject(i);
                            /*Log.i("TEST","codice: "+json_data.getString("Codice")+
                                    ", descrizione: "+json_data.getString("Descrizione")+
                                    ", giacenza: "+json_data.getInt("Giacenza"));

                            Finale =json_data.getString("Codice")+
                                    "@" + json_data.getString("Descrizione")+
                                    "@"+json_data.getString("Fornitore")+
                                    "@"+json_data.getString("Codice Fornitore")+
                                    "@"+json_data.getDouble("Giacenza")+
                                    "@"+json_data.getString("Giacenza Minima")+
                                    "@"+json_data.getString("Prezzo")+
                                    "@"+json_data.getString("Valore")+
                                    "@"+json_data.getString("Quantità Ordinata")+
                                    "@"+json_data.getString("Data Consegna")+
                                    "@"+json_data.getString("Giacenza Simulata")+
                                    "@"+json_data.getString("Produrre")+
                                    "@"+json_data.getString("data_ins")+
                                    "@"+json_data.getString("data_mod")+"\n\n";
                            flag=1;*/


                        }

                    }
                    catch(JSONException e){
                        Log.e("log_tag", "Error parsing data "+e.toString());
                    }
                }else{
                    System.out.println("ERROR1");

                }
            }
            else{//is è null e non ho avuto risposta
                System.out.println("ERROR2");

            }
            System.out.println("ERROR3");

            return stringaFinale;

prendendolo da una vecchia applicazione che avevo fatto ma che teneva tutto in locale

però ad eseguirlo mi da errore quando esegue: JSONArray jArray = new JSONArray(result);

org.json.JSONException: Value {"eventi":[{"descrizione":"gtsthrd","nomeimg":"urzano.png","indirizzo":"","ID":"4","nome":"ye","paese":"hstrhyr","fine":"","inizio":"thsrhyrd"},{"descrizione":"htds","nomeimg":"","indirizzo":"","ID":"3","nome":"htr","paese":"hts","fine":"","inizio":"htsr"}]} of type org.json.JSONObject cannot be converted to JSONArray

ora capisco che non posso convertire un json object in un json array però mi ritrovo bloccato comunque....purtroppo il parsing json non è il mio forte..

Offline LinkOut

  • Utente normale
  • ***
  • Post: 269
  • Respect: +37
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:Parsing JSON con più di un elemento
« Risposta #3 il: 20 Marzo 2015, 13:27:18 CET »
0
Codice (Java): [Seleziona]
 JSONArray jArray = new JSONArray(result);
Io presumo che il tuo result sia l'output... che nel tuo caso è un JSON Object con all'interno un JSON Array di eventi...

Quindi prima devi trasformare il result in JSON Object, poi prelevare il JSON Array al suo interno e scorrere gli elementi...

Magari un tool visuale come : JSON Formatter & Validator potrebbe aiutarti, copia ed incolla dentro il tuo "result" così da vedere come è strutturato in modo semplice.


PS: Se vuoi fare le cose fatte bene. Ti consiglio di vederti Retrofit Per le chiamate REST, imparandolo ad usare, operazioni come quella che vuoi fare tu risultano molto semplici da implementare e da estendere.
« Ultima modifica: 20 Marzo 2015, 13:30:17 CET da LinkOut »

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Parsing JSON con più di un elemento
« Risposta #4 il: 20 Marzo 2015, 17:20:34 CET »
0
Perfetto ora funziona :D

Codice (Java): [Seleziona]
 if((!result.isEmpty())&&(result.length()>5)){
                    //parsing dei dati arrivati in formato json
                    try{
                        Log.i("test", "entrato");
                        JSONObject jobj=new JSONObject(result);
                        JSONArray jArray = jobj.getJSONArray("eventi");
                        Valori.dbEventiNome=new String[jArray.length()];
                        Valori.dbEventiDescrizione=new String[jArray.length()];
                        Valori.dbEventiInizio=new String[jArray.length()];
                        Valori.dbEventiFine=new String[jArray.length()];
                        Valori.dbEventiIndirizzo=new String[jArray.length()];
                        Valori.dbEventiImmagine=new String[jArray.length()];
                        Valori.dbEventiPaese=new String[jArray.length()];

                        for(int i=0;i<jArray.length();i++){
                            JSONObject json_data = jArray.getJSONObject(i);

                            Valori.dbEventiNome[i] =json_data.getString("nome");
                            Valori.dbEventiDescrizione[i] =json_data.getString("descrizione");
                            Valori.dbEventiPaese[i] =json_data.getString("paese");
                            Valori.dbEventiIndirizzo[i] =json_data.getString("indirizzo");
                            Valori.dbEventiInizio[i] =json_data.getString("inizio");
                            Valori.dbEventiFine[i] =json_data.getString("fine");
                            Valori.dbEventiImmagine[i] =json_data.getString("nomeimg");



                        }

                    }

ho usato questo codice per fare il parsing ed è perfetto!!


Ho solo un'ultimo problema, quando nel mio database inserisco una descrizione molto lunga il json mi da valore null, ho provato a controllare se lo inserisce effettivamente nel database e lo fa, l'errore è nel php che uso per creare il json.

Però la stessa pagina php con frasi piccole non da nessun problema.
Codice: [Seleziona]
$con=mysqli_connect($host, $username, $password,$db_name);

// Check connection
if (!$con) {
    die("Connection failed: " . mysqli_connect_error());
}

$sql="SELECT `ID`, `nome`, `descrizione`, `paese`, `indirizzo`, `inizio`, `fine` FROM `eventi` ";
$result = mysqli_query($con, $sql);
$json=array();

if(mysqli_num_rows($result)>0){
//output each data of each row
        while($row=mysqli_fetch_assoc($result)){
                $json['eventi'][]=$row;
        }
}

if(mysqli_num_rows($result)==0){

        echo "0 risultati";
}



print json_encode($json);

mysqli_close($con);

?>

quale potrebbe essere il problema?

Offline LinkOut

  • Utente normale
  • ***
  • Post: 269
  • Respect: +37
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:Parsing JSON con più di un elemento
« Risposta #5 il: 23 Marzo 2015, 09:07:54 CET »
0
Devi vedere il messaggio di errore, potrebbe esserci un limite di caratteri imposto da sql

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Parsing JSON con più di un elemento
« Risposta #6 il: 23 Marzo 2015, 09:27:02 CET »
0
Di messaggi di errore non ne da, mi da questo:

{"ID":"8","nome":"Sagra di S.Lorenzo","descrizione":null,"paese":"Baiso","indirizzo":"Via Montecchio","inizio":"10\/08\/2015","fine":"13\/08\/2015","nomeimg":"baiso.gif"},

insieme al resto di json ovviamente

Offline LinkOut

  • Utente normale
  • ***
  • Post: 269
  • Respect: +37
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:Parsing JSON con più di un elemento
« Risposta #7 il: 23 Marzo 2015, 09:37:54 CET »
0
Citazione
quando nel mio database inserisco una descrizione molto lunga il json mi da valore null...


Quindi tu inserisci correttamente il JSON nel DB, ma in fase di lettura e parsing ci sono problemi?

Allora può essere che cerchi di parserizzare il JSON in modo errato.

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Parsing JSON con più di un elemento
« Risposta #8 il: 23 Marzo 2015, 09:45:42 CET »
0
ho provato a inserire più di un record e questo è il risultato:

{"eventi":[{"ID":"4","nome":"ye","descrizione":"gtsthrd","paese":"hstrhyr","indirizzo":"","inizio":"thsrhyrd","fine":"","nomeimg":"urzano.png"},{"ID":"3","nome":"htr","descrizione":"htds","paese":"hts","indirizzo":"","inizio":"htsr","fine":"","nomeimg":""},{"ID":"5","nome":"Festa1","descrizione":"Festa Delle Feste","paese":"Urzano","indirizzo":"Via casa n9","inizio":"19\/03\/2014","fine":"","nomeimg":"urzano.png"},{"ID":"6","nome":"festa2","descrizione":"lilla","paese":"Urzano","indirizzo":"","inizio":"20\/03\/2015","fine":"","nomeimg":"urzano.png"},{"ID":"8","nome":"Sagra di S.Lorenzo","descrizione":null,"paese":"Baiso","indirizzo":"Via Montecchio","inizio":"10\/08\/2015","fine":"13\/08\/2015","nomeimg":"baiso.gif"},{"ID":"9","nome":"fea","descrizione":"frwaf frwaf grafr","paese":"frwa","indirizzo":"","inizio":"frwaf","fine":"","nomeimg":"baiso.gif"}]}

quelli "corti" me li parsizza(?) correttamente, mentre quello lungo no

Offline LinkOut

  • Utente normale
  • ***
  • Post: 269
  • Respect: +37
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:Parsing JSON con più di un elemento
« Risposta #9 il: 23 Marzo 2015, 09:56:26 CET »
0
Dai che ci siamo quasi, il problema è: "Quando cerco di generare il JSON dal mio DB (quando in questo ci sono molti record) essendo il JSON generato molto "lungo" in output risulta essere null."
Scusa ma non riesco proprio a capire la domanda...
Se la domanda è quella di sopra allora, io penso ad un limite di caratteri, ad un problema di memoria, a qualcosa non gestito a livello di DB.

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Parsing JSON con più di un elemento
« Risposta #10 il: 23 Marzo 2015, 10:15:26 CET »
0
Si esatto xD scusa se sono poco chiaro...

però come limite nel mio db ho messo un varchar di 500... non mi sembra poco....

Offline LinkOut

  • Utente normale
  • ***
  • Post: 269
  • Respect: +37
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:Parsing JSON con più di un elemento
« Risposta #11 il: 23 Marzo 2015, 10:22:24 CET »
0
Il JSON che hai postato sopra ha 865 caratteri :) Prova magari ad aumentarlo.

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Parsing JSON con più di un elemento
« Risposta #12 il: 23 Marzo 2015, 10:29:27 CET »
0
no ok scusa mi correggo è un varchar da 5000 (troppo?)

Offline LinkOut

  • Utente normale
  • ***
  • Post: 269
  • Respect: +37
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:Parsing JSON con più di un elemento
« Risposta #13 il: 23 Marzo 2015, 10:38:26 CET »
0
Citazione
"ID":"4","nome":"ye","descrizione":"gtsthrd","paese":"hstrhyr","indirizzo":"","inizio":"thsrhyrd","fine":"","nomeimg":"urzano.png"
In quell'esempio ci sono 130 caratteri, senza contare le parentesi... Ciò vuol dire che 39 record uguali sono 5070 caratteri... Partendo da questo però, ogni record è diverso, quindi presumo che ci siano record con nomi, descrizioni paese indirizzo etc aventi più caratteri. In quel caso il numero di record per non superare il limite è più basso.
Guarda la tabella di sotto, magari ti chiarisce le idee.

Citazione
Can you predict how long the user input would be?

VARCHAR(X)
Case: user name, email, country, subject, password

TEXT
Case: messages, emails, comments, formatted text, html, code, images, links

MEDIUMTEXT
Case: large json bodies, books, csv strings

LONGTEXT
Case: textbooks, programs, years of logs files, a json list of dead redshirts

Fonte: Stack Overflow

Offline ValerioAdo

  • Utente normale
  • ***
  • Post: 316
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Huawei Ascend g525
  • Sistema operativo:
    windows 8.1
Re:Parsing JSON con più di un elemento
« Risposta #14 il: 23 Marzo 2015, 10:45:14 CET »
0
Ho provato a cambiare il campo descrizione da un varchar ad un longText ma il risultato non cambia, quando faccio il parsing mi da sempre questa riga:
{"ID":"8","nome":"Sagra di S.Lorenzo","descrizione":null,"paese":"Baiso","indirizzo":"Via Montecchio","inizio":"10\/08\/2015","fine":"13\/08\/2015","nomeimg":"baiso.gif"}

con descrizione null mentre negli altri json funzionano benissimo

Post unito: 23 Marzo 2015, 10:49:25 CET
ho trovato questo link che è la mia stessa identica situazione:

php - json_encode is returning NULL? - Stack Overflow

tranne per il fatto che nel mio db c'è latin1_swedish_ci   

probabile che sia quello l'errore?
« Ultima modifica: 23 Marzo 2015, 10:49:25 CET da ValerioAdo, Reason: Merged DoublePost »