Omet navegació

5.2 - API Simple JSON

Hi ha més d'una llibreria per a poder accedir i analitzar els documetns json.

Les que més es comenten per Internet són GSON (de Google) i Jackson. Però nosaltres anem a utilitzar una altra, per la seua senzillesa: JSON.simple.

En el moment de fer aquestos apunts l'última versió estable és la 3.1.0. En aquest enllaç teniu d'on us la podeu baixar: https://jar-download.com/artifacts/com.github.cliftonlabs/json-simple. Una vegada baixada l'haurem d'incorporar al nostre projecte (Project --> Properties --> Java Build Path --> Libraries --> Add Externals JARs)

 En ella trobem el més bàsic:

  • JsonObject: equivaldrà a un objecte
  • JsonArray: equivaldrà a un array
  • Jsoner: contindrà tota l'altra funcionalitat, com l'analitzador (mètode deserialize() ), que agafarà com a entrada el document Json, i tornarà l'objecte arrel. També té el mètode serialize() que fa el procés invers.

Versió 1.1.1

Ja des de la versió 2 van canviar prou les coses respecte de les versions anteriors. Són compatibles les classes de versions anteriors, però estan marcades com a deprecated.

En aquestes notes de color blau us posaré com es feien. Evidentment, si utilitzeu la nova versió no cal que feu les corresponents a versions anteriors.

Si utilitzem la versió 1.1.1, la llibreria és json-simple-1.1.1.jar

Els objectes en aquella versió eren (observeu els canvis de majúscules i minúscules):

  • JSONObject: equivaldrà a un objecte
  • JSONArray: equivaldrà a un array
  • JSONParser: l'analitzador, que agafarà com a entrada el document Json amb el mètode parse, i tornarà l'objecte arrel

Jsoner

El primer que haurem de fer serà analitzar el document per a obtenir l'element arrel (que com hem vist normalment serà un objecte, però de vegades pot ser un array).

El mètode deserialize de Jsoner admet com a paràmetre un string amb tot el document json, però també admet un Reader, que normalment serà el més còmode.

En el següent exemple agafem el json directament d'un string, on teníem els números parells.

{ "p1" : 2 , "p2" : 4 , "p3" : 6 , "p4" : 8 , "p5" : 10 }

Observeu com per a la definició del string ens ha tocat escapar les dobles cometes.

import com.github.cliftonlabs.json_simple.JsonException;
import com.github.cliftonlabs.json_simple.JsonObject;
import com.github.cliftonlabs.json_simple.Jsoner;

public class Exemple_3_51 {

    public static void main(String[] args) throws JsonException {
        String cadena = "{ \"p1\" : 2 , \"p2\" : 4 , \"p3\" : 6 , \"p4\" : 8 , \"p5\" : 10 }";
        
        JsonObject arrel = (JsonObject) Jsoner.deserialize(cadena);
        
        System.out.println(arrel.get("p1"));
    }
}

Mentre que en aquest exemple accedim al fitxer parelles.json (que assumirem que té el mateix contingut). Podríem passar el contingut del fitxer a una cadena, però és molt més còmode passar el Reader com paràmetre, i ell s'encarrega de llegir-lo tot.

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

import com.github.cliftonlabs.json_simple.JsonException;
import com.github.cliftonlabs.json_simple.JsonObject;
import com.github.cliftonlabs.json_simple.Jsoner;


public class Exemple_3_52 {

    public static void main(String[] args) throws JsonException, IOException  {
        
         Reader r_json = new FileReader("parelles.json");
         
         JsonObject arrel = (JsonObject) Jsoner.deserialize(r_json);
         
         System.out.println(arrel.get("p1"));
    }
}

JSONParser

En la versió 1.1.1, hem d'utilitzar el mètode parse de JSONParser per a analitzar. També admetia com a paràmetre un string o un Reader.

Ara el primer exemple quedarà:

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class Exemple_3_51 {

    public static void main(String[] args) throws ParseException {
        String cadena = "{ \"p1\" : 2 , \"p2\" : 4 , \"p3\" : 6 , \"p4\" : 8 , \"p5\" : 10 }";
        
        JSONParser parser = new JSONParser();
        JSONObject arrel = (JSONObject) parser.parse(cadena);
        
        System.out.println(arrel.get("p1"));
    }
}

Mentre que el segon, el que llig del fitxer parelles.json, queda així:

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class Exemple_3_52 {

    public static void main(String[] args) throws IOException, ParseException {
        Reader r_json = new FileReader("parelles.json");
        
        JSONParser parser = new JSONParser();
        JSONObject arrel = (JSONObject) parser.parse(r_json);
        
        System.out.println(arrel.get("p2"));
    }

}

JsonObject

Contindrà un objecte json. Recordeu que l'objecte es delimita amb les claus: {  }

El mètode més important serà get(clau) al qual li passem la clau del membre que volem obtenir. Si el membre és una parella clau-valor, obtindrem directament el valor. Si és un altre objecte, doncs obtindrem l'objecte o també podria ser un array. El cas que siga una parella clau-valor, ja l'hem vist en l'exemple anterior.

En el següent exemple, en el fitxer empleat.json tindrem un empleat

{ "empleat" :
  { "num": 1 ,
    "nom": "Andreu" ,
    "departament": 10 ,
    "edat": 32 ,
    "sou": 1000.0
  }
}

Observeu com ara de l'element arrel hem d'agafar empleat, que és un objecte amb les parelles clau-valor num, nom, ...

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

import com.github.cliftonlabs.json_simple.JsonException;
import com.github.cliftonlabs.json_simple.JsonObject;
import com.github.cliftonlabs.json_simple.Jsoner;

public class Exemple_3_53 {

    public static void main(String[] args) throws IOException, JsonException {
        Reader r_json = new FileReader("empleat.json");
        
        JsonObject arrel = (JsonObject) Jsoner.deserialize(r_json);
        
        JsonObject empleat = (JsonObject) arrel.get("empleat");
        
        System.out.println(empleat.get("nom") + " (" + empleat.get("sou") + ")");
    }
}

En la versió 1.1.1, l'objecte es deia JSONObject (observeu el canvi de majúscules)

JSONArray

Serà l'array, que recordem que ve limitat per els claudàtors: [  ]

Per a obtenir els elements de l'array utilitzarem el mètode get(index), on l'índex és el número d'ordre de l'element que volem obtenir.

Posem el primer exemple sobre un json que només té un array els elements del qual són valors:

[ 5 , 7 , 8 , 7 ]

Observeu com ara l'arrel és un array, i ens muntem un bucle per obtenir tots els elements.

import com.github.cliftonlabs.json_simple.JsonArray;
import com.github.cliftonlabs.json_simple.JsonException;
import com.github.cliftonlabs.json_simple.Jsoner;

public class Exemple_3_54 {

    public static void main(String[] args) throws JsonException {
        String cadena = "[ 5 , 7 , 8 , 7 ]";
        
        JsonArray arrel = (JsonArray) Jsoner.deserialize(cadena);
        
        for (int i=0; i<arrel.size();i++)
            System.out.println(arrel.get(i));
    }
}

També podem fer servir els bucles foreach, però lamentablement no podem obtenir directament un JsonObject, i per tant l'hem de reconvertir. Ho mostrarem en el següent exemple en el qual agafem tots els empleats de l'empresa, on empresa.json és així:

{ "empresa" :
    { "empleats":
           [
        { "num":1, "nom": "Andreu", "departament": 10, "edat": 32, "sou": 1000.0}  ,
        { "num":2, "nom": "Bernat", "departament": 20, "edat": 28, "sou": 1200.0}  ,
        { "num":3, "nom": "Clàudia", "departament": 10, "edat": 26, "sou": 1100.0}  ,
        { "num":4, "nom": "Damià", "departament": 10, "edat": 40, "sou": 1500.0}
       ]
    }
}

Tindrem un objecte arrel, amb només un objecte, empresa, que té un únic membre empleat que és un array amb 4 elements, cadascun dels empleats

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

import com.github.cliftonlabs.json_simple.JsonException;
import com.github.cliftonlabs.json_simple.Jsoner;
import com.github.cliftonlabs.json_simple.JsonObject;
import com.github.cliftonlabs.json_simple.JsonArray;

public class Exemple_3_55 {

    public static void main(String[] args) throws IOException, JsonException {
        Reader r_json = new FileReader("empresa.json");
        
        JsonObject arrel = (JsonObject) Jsoner.deserialize(r_json);
        
        JsonObject empresa = (JsonObject) arrel.get("empresa");
        
        JsonArray empleats = (JsonArray) empresa.get("empleats");
        
        for (Object e : empleats) {
            JsonObject emp = (JsonObject) e;
            System.out.println(emp.get("nom") + " (" + emp.get("sou") + ")");
        }
    }
}

En la versió 1.1.1, l'objecte es deia JSONArray (observeu el canvi de majúscules)