La notación de objetos de JavaScript (JSON) es un formato estándar basado en texto para representar datos estructurados basados en la sintaxis de objetos de JavaScript. Es liviano, flexible y más rápido que XML, razón por la cual se usa ampliamente para el intercambio de datos entre el servidor y el cliente. Si alguna vez trabaja en Java Enterprise Applications, se encontrará con tareas en las que podría necesitar generar y analizar datos JSON para su aplicación. Por ejemplo, los servicios web RESTful usan JSON ampliamente como formato para los datos dentro de las requests y respuestas.
Los siguientes ejemplos muestran un objeto JSON con pares de nombre y valor:
{ "firstName": "Duke", "lastName": "Java", "age": 18, "streetAddress": "100 Internet Dr", "city": "JavaTown", "state": "JA", "postalCode": "12345", "phoneNumbers": [ { "Mobile": "111-111-1111" }, { "Home": "222-222-2222" } ] }
Java proporciona una API para analizar, transformar y consultar datos JSON mediante el modelo de objetos o el modelo de transmisión .
El modelo de objetos funciona mediante la creación de un árbol que representa los datos JSON en la memoria. El modelo de objetos genera una salida JSON navegando por todo el árbol a la vez y, por lo tanto, permite el procesamiento que requiere acceso a todo el contenido del árbol a la vez. El árbol se puede navegar, analizar o modificar. Este enfoque se considera flexible, pero es más lento que el modelo de transmisión y requiere más memoria.
La API de Java proporciona el paquete javax.json , que contiene una interfaz de lectura, una interfaz de escritura y una interfaz de creación de modelos para el modelo de objetos. El paquete también contiene otras clases de utilidades y tipos de Java para elementos JSON.
En el modelo de objetos, se crea una referencia de objeto JSON que representa la raíz del árbol y se puede usar para navegar por el árbol o escribirlo en una secuencia como datos JSON. Esta referencia de objeto JSON creada puede ser de tipo JsonObject o JsonArray, y ambos son subtipos de JsonStructure. Cuál dependerá del formato/contenido del archivo.
Describamos cada uno de ellos para ser precisos y claros.
Repasemos algunas características de JsonObject
- Escrito en pares clave-valor.
- Las claves deben ser strings y los valores deben ser de tipo JSON válido.
- JsonObject comienza y termina con llaves { }.
- El orden no es importante.
El código de muestra para el objeto JSON es el siguiente en la siguiente ilustración
{ "name" : "GeeksforGeeks", "description" : "An educational website" }
Repasemos algunas características de JsonArray
- Se utiliza para organizar una colección de elementos relacionados.
- Los valores pueden ser de tipo string, número, objeto, array, booleano o nulo.
- JsonArray comienza y termina con corchetes [ ].
- El orden es importante.
Ilustración:
[1, 2, 3, 4]
JsonObject y JsonArray también se pueden usar de forma anidada para representar algún tipo especial de datos. Puede usar el objeto dentro de la array o la array dentro del objeto.
{ "employees":[ {"firstName":"John", "lastName":"Doe"}, {"firstName":"Anna", "lastName":"Smith"}, {"firstName":"Peter", "lastName":"Jones"} ], "positions" : [ {"department" : "Testing", "role" : "Junior"}, {"department" : "Testing", "role" : "Senior"}, {"department" : "Design", "role" : "Junior"} ] }
Ahora que tenemos claro los conceptos básicos, podemos aprender a codificar.
Ahora pasemos a instalar la API javax.json. Entonces, si está utilizando un proyecto Maven, agregue esta dependencia a su archivo pom.xml :
<dependency> <groupId>javax.json</groupId> <artifactId>javax.json-api</artifactId> <version>1.1.4</version> </dependency>
De lo contrario, en caso de que esté creando un proyecto normal, agregue el archivo jar javax.json a sus bibliotecas; de lo contrario, descargue el archivo jar desde aquí y siga los pasos a continuación .
Paso 1: crear un modelo de objetos a partir de datos JSON dados
si asumimos que ya tenemos algunos datos en formato JSON y, por lo tanto, queremos convertirlos en un JsonObject de Java, entonces podemos hacer uso de javax.json.JsonStructure .
Supongamos que tenemos un archivo sample.txt que almacena datos JSON de la siguiente manera:
{ "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021" }, "phoneNumber": [ { "type":"home", "number":"212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] }
Además de simplemente crear un objeto de los datos, ¡también necesitamos tener una forma de leer esos datos!
Paso 2: Navegarlo.
Para navegar por los datos, crearemos una función navegarTree() que tomará el objeto/modelo JSON que creamos, como entrada, y para cada objeto o array que encuentre anidado dentro del modelo JSON, volverá a llamar a la función de navegación. , y si el elemento es un valor, imprimirá la salida estándar.
Ahora podemos proceder al código para crear una JsonStructure a partir de este archivo sample.txt , que se muestra a continuación.
Ejemplo
Java
// Java Program to create a JsonStructure of an already // existing data in the JSON format // Importing required classes import java.io.FileNotFoundException; import java.io.FileReader; import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonNumber; import javax.json.JsonObject; import javax.json.JsonReader; import javax.json.JsonString; import javax.json.JsonStructure; import javax.json.JsonValue; // Main class public class CreateObjectModelFromJSONData { // Main driver method public static void main(String args[]) throws FileNotFoundException { // JsonReader: an interface that reads a JSON object // or an array structure from an input source. JsonReader reader = Json.createReader( new FileReader("sample.txt")); // JsonStructure: an interface that is a super type // for the two structured types in JSON // (objects and arrays) JsonStructure jsonst = reader.read(); // navigateTree method takes two arguments: a JSON // element and a key. The key is used only to help // print the key-value pairs inside objects. // Elements in a tree are represented by the // JsonValue type. navigateTree(jsonst, null); } // A JsonValue is one of the following: an object // (JsonObject), an array (JsonArray), a number // (JsonNumber), a string (JsonString), true // (JsonValue.TRUE), false (JsonValue.FALSE), or null // (JsonValue.NULL). // Method 2 // To navigate through the model // and print the key-value pairs public static void navigateTree(JsonValue tree, String key) { if (key != null) System.out.print("Key " + key + ": "); // Switch case // Method 3 // getValueType() returns the value type of // this JSON value. switch (tree.getValueType()) { // Case 1 case OBJECT: System.out.println("OBJECT"); JsonObject object = (JsonObject)tree; for (String name : object.keySet()) navigateTree(object.get(name), name); break; // Case 2 case ARRAY: System.out.println("ARRAY"); JsonArray array = (JsonArray)tree; for (JsonValue val : array) navigateTree(val, null); break; // Case 3 case STRING: JsonString st = (JsonString)tree; System.out.println("STRING " + st.getString()); break; // Case 4 case NUMBER: JsonNumber num = (JsonNumber)tree; System.out.println("NUMBER " + num.toString()); break; // Case 5 case TRUE: // Case 6 case FALSE: // Case 7 case NULL: // Print statement System.out.println( tree.getValueType().toString()); break; } } }
Producción
OBJECT Key firstName: STRING John Key lastName: STRING Smith Key age: NUMBER 25 Key address: OBJECT Key streetAddress: STRING 21 2nd Street Key city: STRING New York Key state: STRING NY Key postalCode: STRING 10021 Key phoneNumber: ARRAY OBJECT Key type: STRING home Key number: STRING 212 555-1234 OBJECT Key type: STRING fax Key number: STRING 646 555-4567
2. Crear un modelo de objetos a partir de código
Para crear un modelo de objetos propio desde cero, utilizaremos la clase JSON que proporciona un método createObjectBuilder() que crea un generador de objetos JSON. La interfaz JsonObjectBuilder actúa como un generador para crear modelos JsonObject desde cero. Esta interfaz inicializa un modelo de objeto JSON vacío y proporciona métodos para agregar pares de nombre/valor al modelo de objeto y devolver el objeto resultante. Los métodos de esta clase se pueden enstringr para agregar varios pares de nombre/valor al objeto.
Ejemplo
Java
// Java Program to create a Json object from scratch using // JsonObjectBuilder and navigate it. // Importing required classes import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonNumber; import javax.json.JsonObject; import javax.json.JsonString; import javax.json.JsonValue; // Main class // CreateObjectModelFromCode public class GFG { // Method 1 // Main driver method public static void main(String args[]) { // add() method adds a name/value pair to the JSON // object associated with this object builder. // build() method returns the JSON object associated // with this object builder. JsonObject model = Json.createObjectBuilder() .add("firstName", "Duke") .add("lastName", "Java") .add("age", 18) .add("streetAddress", "100 Internet Dr") .add("city", "JavaTown") .add("state", "JA") .add("postalCode", "12345") .add("phoneNumbers", Json.createArrayBuilder() .add(Json.createObjectBuilder() .add("type", "mobile") .add("number", "111-111-1111")) .add(Json.createObjectBuilder() .add("type", "home") .add("number", "222-222-2222"))) .build(); // The same navigateTree() method can be used to // navigate this model. navigateTree(model, null); } // Method 2 public static void navigateTree(JsonValue tree, String key) { if (key != null) System.out.print("Key " + key + ": "); // Method 3- getValueType() // To get the value types // Switch case switch (tree.getValueType()) { // Case 1 case OBJECT: System.out.println("OBJECT"); JsonObject object = (JsonObject)tree; for (String name : object.keySet()) navigateTree(object.get(name), name); break; // Case 2 case ARRAY: System.out.println("ARRAY"); JsonArray array = (JsonArray)tree; for (JsonValue val : array) navigateTree(val, null); break; // Case 3 case STRING: JsonString st = (JsonString)tree; System.out.println("STRING " + st.getString()); break; // Case 4 case NUMBER: JsonNumber num = (JsonNumber)tree; System.out.println("NUMBER " + num.toString()); break; // Case 5 case TRUE: // Case 6 case FALSE: // Case 7 case NULL: System.out.println( tree.getValueType().toString()); break; } } }
Producción
OBJECT Key firstName: STRING Duke Key lastName: STRING Java Key age: NUMBER 18 Key streetAddress: STRING 100 Internet Dr Key city: STRING JavaTown Key state: STRING JA Key postalCode: STRING 12345 Key phoneNumbers: ARRAY OBJECT Key type: STRING mobile Key number: STRING 111-111-1111 OBJECT Key type: STRING home Key number: STRING 222-222-2222
3. Escribir el modelo de objetos en un flujo
Los modelos de objetos que creamos en los ejemplos anteriores se pueden escribir en una secuencia mediante la clase JsonWriter. JsonWriter escribe un objeto JSON o una estructura de array en una fuente de salida. Esta vez, escribiremos el contenido de sample.txt en un flujo de salida después de haberlo convertido en JsonStructure.
Ejemplo
Java
// Java Program to Write the Object Model to an Output Stream // Importing required classes import java.io.FileNotFoundException; import java.io.FileReader; import java.io.StringWriter; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonReader; import javax.json.JsonStructure; import javax.json.JsonWriter; // Main class // WritingObjectModelToAStream public class GFG { // Main driver method public static void main(String args[]) throws FileNotFoundException { JsonReader reader = Json.createReader( new FileReader("sample.txt")); JsonStructure jsonst = reader.read(); StringWriter stWriter = new StringWriter(); // We use try-with-resources to close the JSON // writer automatically // Json.createWriter() method takes an output stream // as a parameter. JsonWriter.writeObject() method // writes the object to the stream. // Try block to check for exceptions try (JsonWriter jsonWriter = Json.createWriter(stWriter)) { jsonWriter.writeObject((JsonObject)jsonst); } // Creating variable jsonData to store the object // written to the stream in the form of a String String jsonData = stWriter.toString(); // Print the data string System.out.println(jsonData); } }
Salida: En la consola , se imprimirá lo siguiente en una sola línea
{ "firstName":"John","lastName":"Smith","age":25, "address":{"streetAddress":"21 2nd Street","city":"New York","state":"NY","postalCode":"10021"}, "phoneNumber":[{"type":"home","number":"212 555-1234"},{"type":"fax","number":"646 555-4567"}] }
Ahora pensando en el siguiente modelo,
El modelo de transmisión utiliza un analizador basado en eventos que lee los datos JSON elemento por elemento. El modelo de transmisión genera una salida JSON para una transmisión determinada al realizar una llamada de función con un elemento a la vez. Este enfoque es adecuado para el procesamiento local, en el que el procesamiento de un elemento no requiere información del resto de los datos. La forma en que funciona es que el analizador genera eventos y se detiene para procesar cada vez que encuentra una clave, un valor o llega al principio o al final de un objeto o array. El elemento encontrado se puede procesar o descartar según el código y luego el analizador pasa al siguiente evento.
La API de Java proporciona el paquete javax.json.stream , que contiene una interfaz de analizador, JsonParser, y una interfaz de generador, JsonGenerator para el modelo de transmisión. La interfaz JsonParser contiene métodos para analizar JSON en forma de transmisión. La interfaz JsonGenerator contiene métodos para escribir JSON en una fuente de salida en forma de transmisión.
En el próximo código , utilizaremos el mismo archivo sample.txt para analizarlo.
1. Lectura de datos JSON mediante un analizador: utilizaremos el JsonParser que proporciona acceso directo de solo lectura a los datos JSON de forma continua. JsonParser analiza JSON mediante el modelo de programación de análisis de extracción. En este modelo , el código del cliente controla el hilo y llama al método next() para avanzar el analizador al siguiente estado después de procesar cada elemento. El analizador puede generar los siguientes eventos:
START_OBJECT, END_OBJECT, START_ARRAY, END_ARRAY, KEY_NAME, VALUE_STRING, VALUE_NUMBER, VALUE_TRUE, VALUE_FALSE, and VALUE_NULL.
En el siguiente código realizaremos los siguientes pasos:
- Obtenga los datos JSON en forma de string, para que puedan pasarse al objeto del analizador.
- Obtenga una instancia de analizador llamando al método estático JSON.createParser y pásele la string.
- Repita los eventos del analizador con los métodos JsonParser.hasNext y JsonParser.next.
- Realice el procesamiento local para cada elemento.
Implementación:
Ejemplo
Java
// Java program to Read JSON data using a JsonParser // Importing required classes import java.io.FileNotFoundException; import java.io.FileReader; import java.io.StringReader; import java.io.StringWriter; import javax.json.Json; import javax.json.JsonObject; import javax.json.JsonReader; import javax.json.JsonStructure; import javax.json.JsonWriter; import javax.json.stream.JsonParser; // Main class // ReadingJSONDataUsingAParser public class GFG { // Main driver method public static void main(String args[]) throws FileNotFoundException { // Creating object of JsonReader class // Creating object of JsonStructure class JsonReader reader = Json.createReader( new FileReader("sample.txt")); JsonStructure jsonst = reader.read(); StringWriter stWriter = new StringWriter(); // Try block to check for exceptions try (JsonWriter jsonWriter = Json.createWriter(stWriter)) { jsonWriter.writeObject((JsonObject)jsonst); } // Step 1 String jsonData = stWriter.toString(); // Step 2 // Json.createParser(): Creates a JSON parser from a // character stream. JsonParser parser = Json.createParser(new StringReader(jsonData)); // Step 3 // haNext(): Returns true if there are more parsing // states. This method returns false if the parser // reaches the end of the JSON text while (parser.hasNext()) { // JsonParser.Event: An event from JsonParser. // next(): Returns the event for the next // parsing state. JsonParser.Event event = parser.next(); // Step 4 // Switch case switch (event) { // Case 1 // Start of a JSON array. case START_ARRAY: // Case 2 // End of a JSON array. case END_ARRAY: // Case 3 // Start of a JSON object. case START_OBJECT: // Case 4 // End of a JSON object. case END_OBJECT: // Case 5 // False value in a JSON array or object. case VALUE_FALSE: // Case 6 // Null value in a JSON array or object. case VALUE_NULL: // Case 7 // True value in a JSON array or object. case VALUE_TRUE: System.out.println(event.toString()); break; // Case 8 // Name in a name/value pair of a JSON object. case KEY_NAME: System.out.print(event.toString() + " " + parser.getString() + " - "); break; // Case 9 // String value in a JSON array or object. case VALUE_STRING: // Case 10 // Number value in a JSON array or object. case VALUE_NUMBER: System.out.println(event.toString() + " " + parser.getString()); break; } } } }
Producción:
START_OBJECT KEY_NAME firstName - VALUE_STRING John KEY_NAME lastName - VALUE_STRING Smith KEY_NAME age - VALUE_NUMBER 25 KEY_NAME address - START_OBJECT KEY_NAME streetAddress - VALUE_STRING 21 2nd Street KEY_NAME city - VALUE_STRING New York KEY_NAME state - VALUE_STRING NY KEY_NAME postalCode - VALUE_STRING 10021 END_OBJECT KEY_NAME phoneNumber - START_ARRAY START_OBJECT KEY_NAME type - VALUE_STRING home KEY_NAME number - VALUE_STRING 212 555-1234 END_OBJECT START_OBJECT KEY_NAME type - VALUE_STRING fax KEY_NAME number - VALUE_STRING 646 555-4567 END_OBJECT END_ARRAY END_OBJECT
2. Escribir datos JSON usando Generator
Usando JsonGenerator, podemos escribir datos JSON en una fuente de salida en forma de transmisión. Obtenga un generador JSON llamando al método estático Json.createGenerator, que toma un escritor o un flujo de salida como parámetro. Escribiremos los datos JSON en un archivo details.txt .
Ejemplo
Java
// Java Program to Generate JSON data and Store it into a // file. // Importing required classes import java.io.FileWriter; import java.io.IOException; import javax.json.Json; import javax.json.stream.JsonGenerator; // Main class // WriteJSONDataUsingGenerator public class GFG { // Main driver method public static void main(String args[]) { FileWriter writer = null; // Try block to check for exceptions try { writer = new FileWriter("details.txt"); } // Catch block to handle i/o exceptions catch (IOException e) { // Print the exceptions along with line number // using printStackTrace() method e.printStackTrace(); } // Json.createGenerator(): Creates a JSON generator // for writing JSON to a character stream. JsonGenerator generator = Json.createGenerator(writer); // writeStartObject(): Writes the JSON name/start // object character pair in the current object // context. write(): Writes a JSON name/string value // pair in the current object context. writeEnd(): // Writes the end of the current context. // writeStartArray(): Writes the JSON name/start // array character pair with in the current object // context. generator.writeStartObject() .write("firstName", "John") .write("lastName", "Smith") .write("age", 25) .writeStartObject("address") .write("streetAddress", "21 2nd Street") .write("city", "New York") .write("state", "NY") .write("postalCode", "10021") .writeEnd() .writeStartArray("phoneNumber") .writeStartObject() .write("type", "home") .write("number", "212 555-1234") .writeEnd() .writeStartObject() .write("type", "fax") .write("number", "646 555-4567") .writeEnd() .writeEnd() .writeEnd(); // Closes this generator and frees any resources // associated with it using close() method generator.close(); } }
Salida: En el archivo detalles.txt se escribirán los siguientes datos en una sola línea:
{ "firstName":"John","lastName":"Smith","age":25, "address":{"streetAddress":"21 2nd Street","city":"New York","state":"NY","postalCode":"10021"}, "phoneNumber":[{"type":"home","number":"212 555-1234"},{"type":"fax","number":"646 555-4567"}] }
Publicación traducida automáticamente
Artículo escrito por yuvrajjoshi31 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA