1. Introducción a JSON-Java
JSON (acrónimo de JavaScript Object Notation) es un formato ligero de intercambio de datos y se utiliza con mayor frecuencia para la comunicación cliente-servidor. Es fácil de leer / escribir e independiente del idioma. Un valor JSON puede ser otro objeto JSON , matriz, número, cadena, booleano (verdadero / falso) o nulo.
En este tutorial, veremos cómo podemos crear, manipular y analizar JSON usando una de las bibliotecas de procesamiento JSON disponibles, es decir, la biblioteca JSON-Java también se conoce como org.json.
2. Requisito previo
Antes de comenzar, necesitaremos agregar la siguiente dependencia en nuestro pom.xml :
org.json json 20180130
La última versión se puede encontrar en el repositorio de Maven Central.
Tenga en cuenta que este paquete ya se ha incluido en el SDK de Android, por lo que no deberíamos incluirlo mientras lo usamos.
3. JSON en Java [paquete org.json]
La biblioteca JSON-Java también se conoce como org.json (que no debe confundirse con org.json.simple de Google) nos proporciona clases que se utilizan para analizar y manipular JSON en Java.
Además, esta biblioteca también puede convertir entre JSON, XML, encabezados HTTP, cookies, listas o textos delimitados por comas, etc.
En este tutorial, veremos:
- JSONObject : similar al objeto similar al mapa nativo de Javaque almacena pares clave-valor desordenados
- JSONArray : una secuencia ordenada de valores similar a la implementación nativa de Vector de Java
- JSONTokener : una herramienta que divide un fragmento de texto en una serie de tokens que JSONObject o JSONArray pueden usar para analizar cadenas JSON
- CDL : una herramienta que proporciona métodos para convertir texto delimitado por comas en un JSONArray y viceversa
- Cookie : convierte de JSON String a cookies y viceversa
- HTTP : se utiliza para convertir de JSON String a encabezados HTTP y viceversa
- JSONException : esta es una excepción estándar lanzada por esta biblioteca
4. JSONObject
Un JSONObject es una colección desordenada de pares de clave y valor, que se asemeja a las implementaciones de mapas nativas de Java .
- Las claves son cadenas únicas que no pueden ser nulas
- Los valores pueden ser cualquier cosa, desde un objeto Boolean , Number , String , JSONArray o incluso un objeto JSONObject.NULL
- Un JSONObject se puede representar mediante una cadena encerrada entre llaves con claves y valores separados por dos puntos y pares separados por una coma
- Tiene varios constructores con los que construir un JSONObject
También admite los siguientes métodos principales:
- get (String key): obtiene el objeto asociado con la clave proporcionada, lanza JSONException si no se encuentra la clave
- opt (clave de cadena): obtiene el objeto asociado con la clave proporcionada, nulo en caso contrario
- put (clave de cadena, valor de objeto): inserta o reemplaza un par clave-valor en JSONObject actual .
El método put () es un método sobrecargado que acepta una clave de tipo String y varios tipos para el valor.
Para obtener la lista completa de métodos admitidos por JSONObject , visite la documentación oficial.
Analicemos ahora algunas de las operaciones principales admitidas por esta clase.
4.1. Creando JSON directamente desde JSONObject
JSONObject expone una API similar a la interfaz Map de Java . Podemos usar el método put () y proporcionar la clave y el valor como argumento:
JSONObject jo = new JSONObject(); jo.put("name", "jon doe"); jo.put("age", "22"); jo.put("city", "chicago");
Ahora nuestro JSONObject se vería así:
{"city":"chicago","name":"jon doe","age":"22"}
Hay siete firmas sobrecargadas diferentes del método JSONObject.put () . Si bien la clave solo puede ser una cadena única y no nula , el valor puede ser cualquier cosa.
4.2. Crear JSON desde el mapa
En lugar de poner directamente la clave y los valores en un JSONObject , podemos construir un mapa personalizado y luego pasarlo como un argumento al constructor de JSONObject .
Este ejemplo producirá los mismos resultados que el anterior:
Map map = new HashMap(); map.put("name", "jon doe"); map.put("age", "22"); map.put("city", "chicago"); JSONObject jo = new JSONObject(map);
4.3. Creando JSONObject desde JSON String
Para analizar una cadena JSON en un objeto JSON , podemos simplemente pasar la cadena al constructor.
Este ejemplo producirá los mismos resultados que el anterior:
JSONObject jo = new JSONObject( "{\"city\":\"chicago\",\"name\":\"jon doe\",\"age\":\"22\"}" );
El argumento String pasado debe ser un JSON válido; de lo contrario, este constructor puede lanzar una JSONException .
4.4. Serializar el objeto Java en JSON
Uno de los constructores de JSONObject toma un POJO como argumento. En el siguiente ejemplo, el paquete usa los captadores de la clase DemoBean y crea un JSONObject apropiado para el mismo.
To get a JSONObject from a Java Object, we'll have to use a class that is a valid Java Bean:
DemoBean demo = new DemoBean(); demo.setId(1); demo.setName("lorem ipsum"); demo.setActive(true); JSONObject jo = new JSONObject(demo);
The JSONObject jo for this example is going to be:
{"name":"lorem ipsum","active":true,"id":1}
Although we have a way to serialize a Java object to JSON string, there is no way to convert it back using this library.
If we want that kind of flexibility, we can switch to other libraries such as Jackson.
5. JSONArray
A JSONArray is an ordered collection of values, resembling Java's native Vector implementation.
- Values can be anything from a Number, String, Boolean, JSONArray, JSONObject or even a JSONObject.NULL object
- It's represented by a String wrapped within Square Brackets and consists of a collection of values separated by commas
- Like JSONObject, it has a constructor that accepts a source String and parses it to construct a JSONArray
The following are the primary methods of the JSONArray class:
- get(int index) – returns the value at the specified index(between 0 and total length – 1), otherwise throws a JSONException
- opt(int index) – returns the value associated with an index (between 0 and total length – 1). If there's no value at that index, then a null is returned
- put(Object value) – append an object value to this JSONArray. This method is overloaded and supports a wide range of data types
For a complete list of methods supported by JSONArray, visit the official documentation.
5.1. Creating JSONArray
Once we've initialized a JSONArray object, we can simply add and retrieve elements using the put() and get() methods:
JSONArray ja = new JSONArray(); ja.put(Boolean.TRUE); ja.put("lorem ipsum"); JSONObject jo = new JSONObject(); jo.put("name", "jon doe"); jo.put("age", "22"); jo.put("city", "chicago"); ja.put(jo);
Following would be contents of our JSONArray(code is formatted for clarity):
[ true, "lorem ipsum", { "city": "chicago", "name": "jon doe", "age": "22" } ]
5.2. Creating JSONArray Directly from JSON String
Like JSONObject the JSONArray also has a constructor that creates a Java object directly from a JSON String:
JSONArray ja = new JSONArray("[true, \"lorem ipsum\", 215]");
This constructor may throw a JSONException if the source String isn't a valid JSON String.
5.3. Creating JSONArray Directly from a Collection or an Array
The constructor of JSONArray also supports collection and array objects as arguments.
We simply pass them as an argument to the constructor and it will return a JSONArray object:
List list = new ArrayList(); list.add("California"); list.add("Texas"); list.add("Hawaii"); list.add("Alaska"); JSONArray ja = new JSONArray(list);
Now our JSONArray consists of:
["California","Texas","Hawaii","Alaska"]
6. JSONTokener
A JSONTokener takes a source String as input to its constructor and extracts characters and tokens from it. It's used internally by classes of this package (like JSONObject, JSONArray) to parse JSON Strings.
There may not be many situations where we'll directly use this class as the same functionality can be achieved using other simpler methods (like string.toCharArray()):
JSONTokener jt = new JSONTokener("lorem"); while(jt.more()) { Log.info(jt.next()); }
Now we can access a JSONTokener like an iterator, using the more() method to check if there are any remaining elements and next() to access the next element.
The tokens received from the previous example will be:
l o r e m
7. CDL
We're provided with a CDL (Comma Delimited List) class to convert comma delimited text into a JSONArray and vice versa.
7.1. Producing JSONArray Directly from Comma Delimited Text
In order to produce a JSONArray directly from the comma-delimited text, we can use the static method rowToJSONArray() which accepts a JSONTokener:
JSONArray ja = CDL.rowToJSONArray(new JSONTokener("England, USA, Canada"));
Our JSONArray now consists of:
["England","USA","Canada"]
7.2. Producing Comma Delimited Text from JSONArray
In order to reverse of the previous step and get back the comma-delimited text from JSONArray, we can use:
JSONArray ja = new JSONArray("[\"England\",\"USA\",\"Canada\"]"); String cdt = CDL.rowToString(ja);
The Stringcdt now contains:
England,USA,Canada
7.3. Producing JSONArray of JSONObjects Using Comma Delimited Text
To produce a JSONArray of JSONObjects, we'll use a text String containing both headers and data separated by commas.
The different lines are separated using a carriage return (\r) or line feed (\n).
The first line is interpreted as a list of headers and all the subsequent lines are treated as data:
String string = "name, city, age \n" + "john, chicago, 22 \n" + "gary, florida, 35 \n" + "sal, vegas, 18"; JSONArray result = CDL.toJSONArray(string);
The object JSONArray result now consists of (output formatted for the sake of clarity):
[ { "name": "john", "city": "chicago", "age": "22" }, { "name": "gary", "city": "florida", "age": "35" }, { "name": "sal", "city": "vegas", "age": "18" } ]
Notice that in this example, both data and header were supplied within the same String.There's an alternative way of doing this where we can achieve the same functionality by supplying a JSONArray that would be used to get the headers and a comma-delimited String working as the data.
Different lines are separated using a carriage return (\r) or line feed (\n):
JSONArray ja = new JSONArray(); ja.put("name"); ja.put("city"); ja.put("age"); String string = "john, chicago, 22 \n" + "gary, florida, 35 \n" + "sal, vegas, 18"; JSONArray result = CDL.toJSONArray(ja, string);
Here we'll get the contents of object result exactly as before.
8. Cookie
The Cookie class deals with web browser cookies and has methods to convert a browser cookie into a JSONObject and vice versa.
Here are the main methods of the Cookie class:
- toJsonObject(String sourceCookie) – converts a cookie string into a JSONObject
- toString(JSONObject jo) – this is reverse of the previous method, converts a JSONObject into a cookie String.
8.1. Converting a Cookie String into a JSONObject
To convert a cookie String to a JSONObject, well use the static method Cookie.toJSONObject():
String cookie = "username=John Doe; expires=Thu, 18 Dec 2013 12:00:00 UTC; path=/"; JSONObject cookieJO = Cookie.toJSONObject(cookie);
8.2. Converting a JSONObject into Cookie String
Now we'll convert a JSONObject into cookie String. This is reverse of the previous step:
String cookie = Cookie.toString(cookieJO);
9. HTTP
The HTTP class contains static methods that are used to convert HTTP headers to JSONObject and vice versa.
This class also has two main methods:
- toJsonObject(String sourceHttpHeader) – converts a HttpHeader String to JSONObject
- toString(JSONObject jo) – converts the supplied JSONObject to String
9.1. Converting JSONObject to HTTP Header
HTTP.toString() method is used to convert a JSONObject to HTTP header String:
JSONObject jo = new JSONObject(); jo.put("Method", "POST"); jo.put("Request-URI", "//www.example.com/"); jo.put("HTTP-Version", "HTTP/1.1"); String httpStr = HTTP.toString(jo);
Here, our String httpStr will consist of:
POST "//www.example.com/" HTTP/1.1
Note that while converting an HTTP request header, the JSONObject must contain “Method”,“Request-URI” and “HTTP-Version” keys, whereas, for response header, the object must contain “HTTP-Version”,“Status-Code” and “Reason-Phrase” parameters.
9.2. Converting HTTP Header String Back to JSONObject
Here we will convert the HTTP string that we got in the previous step back to the very JSONObject that we created in that step:
JSONObject obj = HTTP.toJSONObject("POST \"//www.example.com/\" HTTP/1.1");
10. JSONException
The JSONException is the standard exception thrown by this package whenever any error is encountered.
Esto se usa en todas las clases de este paquete. La excepción suele ir seguida de un mensaje que indica qué salió mal exactamente.
11. Conclusión
En este tutorial, analizamos un JSON usando Java - org.json - y nos enfocamos en algunas de las funciones principales disponibles aquí.
Los fragmentos de código completos utilizados en este artículo se pueden encontrar en GitHub.