Buscar..


Introducción

JSON (JavaScript Object Notation) es un formato de intercambio de datos ligero, basado en texto e independiente del idioma que es fácil de leer y escribir para los humanos y las máquinas. JSON puede representar dos tipos estructurados: objetos y matrices. JSON se usa a menudo en aplicaciones Ajax, configuraciones, bases de datos y servicios web RESTful. La API de Java para el procesamiento de JSON proporciona API portátiles para analizar, generar, transformar y consultar JSON.

Observaciones

Este ejemplo se enfoca en analizar y crear JSON en Java usando varias bibliotecas, como la biblioteca de Google Gson , Jackson Object Mapper y otras.

Los ejemplos que utilizan otras bibliotecas se pueden encontrar aquí: Cómo analizar JSON en Java

Codificación de datos como JSON

Si necesita crear un objeto JSONObject y colocar datos en él, considere el siguiente ejemplo:

// Create a new javax.json.JSONObject instance.
JSONObject first = new JSONObject();

first.put("foo", "bar");
first.put("temperature", 21.5);
first.put("year", 2016);

// Add a second object.
JSONObject second = new JSONObject();
second.put("Hello", "world");
first.put("message", second);

// Create a new JSONArray with some values
JSONArray someMonths = new JSONArray(new String[] { "January", "February" });
someMonths.put("March");
// Add another month as the fifth element, leaving the 4th element unset.
someMonths.put(4, "May");

// Add the array to our object
object.put("months", someMonths);

// Encode
String json = object.toString();

// An exercise for the reader: Add pretty-printing!
/* {
       "foo":"bar",
       "temperature":21.5,
       "year":2016,
       "message":{"Hello":"world"},
       "months":["January","February","March",null,"May"]
   }
*/

Decodificación de datos JSON

Si necesita obtener datos de un JSONObject , considere el siguiente ejemplo:

String json = "{\"foo\":\"bar\",\"temperature\":21.5,\"year\":2016,\"message\":{\"Hello\":\"world\"},\"months\":[\"January\",\"February\",\"March\",null,\"May\"]}";

// Decode the JSON-encoded string
JSONObject object = new JSONObject(json);

// Retrieve some values
String foo = object.getString("foo");
double temperature = object.getDouble("temperature");
int year = object.getInt("year");

// Retrieve another object
JSONObject secondary = object.getJSONObject("message");
String world = secondary.getString("Hello");

// Retrieve an array
JSONArray someMonths = object.getJSONArray("months");
// Get some values from the array
int nMonths = someMonths.length();
String february = someMonths.getString(1);

Métodos optXXX vs getXXX

JSONObject y JSONArray tienen algunos métodos que son muy útiles al tratar con la posibilidad de que un valor que está tratando de obtener no exista o sea de otro tipo.

JSONObject obj = new JSONObject();
obj.putString("foo", "bar");

// For existing properties of the correct type, there is no difference
obj.getString("foo");        // returns "bar"
obj.optString("foo");        // returns "bar"
obj.optString("foo", "tux"); // returns "bar"

// However, if a value cannot be coerced to the required type, the behavior differs
obj.getInt("foo");      // throws JSONException
obj.optInt("foo");      // returns 0
obj.optInt("foo", 123); // returns 123

// Same if a property does not exist
obj.getString("undefined");        // throws JSONException
obj.optString("undefined");        // returns ""
obj.optString("undefined", "tux"); // returns "tux"

Las mismas reglas se aplican a los métodos getXXX / optXXX de JSONArray .

Objeto a JSON (Gson Library)

Asumamos que tienes una clase llamada Person con solo name

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Código:

Gson g = new Gson();

Person person = new Person("John");
System.out.println(g.toJson(person)); // {"name":"John"}

Por supuesto, el tarro de Gson debe estar en el classpath.

JSON a Objeto (Biblioteca Gson)

Asumamos que tienes una clase llamada Person con solo name

private class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Código:

Gson gson = new Gson();
String json = "{\"name\": \"John\"}";

Person person = gson.fromJson(json, Person.class);
System.out.println(person.name); //John

Debes tener gson library en tu classpath.

Extraer un solo elemento de JSON

String json = "{\"name\": \"John\", \"age\":21}";

JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();

System.out.println(jsonObject.get("name").getAsString()); //John
System.out.println(jsonObject.get("age").getAsInt()); //21

Usando Jackson Object Mapper

Modelo de pojo

public class Model {
    private String firstName;
    private String lastName;
    private int age;
    /* Getters and setters not shown for brevity */        
}

Ejemplo: Cadena a objeto

Model outputObject = objectMapper.readValue(
     "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"age\":23}",
     Model.class);
System.out.println(outputObject.getFirstName());
//result: John

Ejemplo: Objeto a Cadena

String jsonString = objectMapper.writeValueAsString(inputObject));
//result: {"firstName":"John","lastName":"Doe","age":23}

Detalles

Declaración de importación necesaria:

import com.fasterxml.jackson.databind.ObjectMapper;

Dependencia de Maven: Jackson-databind

Instancia de ObjectMapper

//creating one
ObjectMapper objectMapper = new ObjectMapper();
  • ObjectMapper es seguro para hilos
  • recomendado: tener una instancia compartida, estática

Deserialización:

<T> T readValue(String content, Class<T> valueType)  
  • valueType necesita ser especificado - la devolución será de este tipo
  • Arroja
    • IOException - en caso de un problema de E / S de bajo nivel
    • JsonParseException : si la entrada subyacente contiene contenido no válido
    • JsonMappingException : si la estructura JSON de entrada no coincide con la estructura del objeto

Ejemplo de uso (jsonString es la cadena de entrada):

Model fromJson = objectMapper.readValue(jsonString, Model.class);

Método para la serialización:

String writeValueAsString (valor de objeto)

  • Arroja
    • JsonProcessingException en caso de error
    • Nota: antes de la versión 2.1, la cláusula throws incluía IOException; 2.1 lo eliminó.

Iteración json

JSONObject sobre propiedades JSONObject

JSONObject obj = new JSONObject("{\"isMarried\":\"true\", \"name\":\"Nikita\", \"age\":\"30\"}");
Iterator<String> keys = obj.keys();//all keys: isMarried, name & age
while (keys.hasNext()) {                      //as long as there is another key
      String key = keys.next();               //get next key 
      Object value = obj.get(key);            //get next value by key
      System.out.println(key + " : " + value);//print key : value
}

JSONArray sobre los valores de JSONArray

JSONArray arr = new JSONArray();        //Initialize an empty array
//push (append) some values in:
arr.put("Stack");
arr.put("Over");
arr.put("Flow");
for (int i = 0; i < arr.length(); i++) {//iterate over all values
    Object value = arr.get(i);          //get value
    System.out.println(value);          //print each value
}

JSON Builder - métodos de encadenamiento

Puede utilizar el encadenamiento de métodos mientras trabaja con JSONObject y JSONArray .

Ejemplo de JSONObject

JSONObject obj = new JSONObject();//Initialize an empty JSON object 
//Before: {}
obj.put("name","Nikita").put("age","30").put("isMarried","true");
//After: {"name":"Nikita","age":30,"isMarried":true}

JSONArray

JSONArray arr = new JSONArray();//Initialize an empty array
//Before: []
arr.put("Stack").put("Over").put("Flow");
//After: ["Stack","Over","Flow"]

JSONObject.NULL

Si necesita agregar una propiedad con un valor null , debe usar el JSONObject.NULL final estático predefinido y no la referencia null Java estándar.

JSONObject.NULL es un valor centinela utilizado para definir explícitamente una propiedad con un valor vacío.

JSONObject obj = new JSONObject();
obj.put("some", JSONObject.NULL);   //Creates: {"some":null}
System.out.println(obj.get("some"));//prints: null

Nota

JSONObject.NULL.equals(null); //returns true

Que es una clara violación del Java.equals() de Java.equals() :

Para cualquier valor de referencia que no sea nulo x, x.equals (nulo) debe devolver falso

JsonArray a la lista de Java (Gson Library)

Aquí hay un JsonArray simple que le gustaría convertir a un ArrayList Java:

{
    "list": [
                "Test_String_1",
                "Test_String_2"
            ] 
}

Ahora pase la 'lista' de JsonArray al siguiente método que devuelve una ArrayList Java correspondiente:

public ArrayList<String> getListString(String jsonList){
    Type listType = new TypeToken<List<String>>() {}.getType();
    //make sure the name 'list' matches the name of 'JsonArray' in your 'Json'.
    ArrayList<String> list = new Gson().fromJson(jsonList, listType);    
    return list;
}

Debe agregar la siguiente dependencia de POM.xml a su archivo POM.xml :

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.7</version>
</dependency>

O deberías tener el jar com.google.code.gson:gson:jar:<version> en tu classpath.

Deserializar la colección JSON a la colección de Objetos usando Jackson

Supongamos que tienes una Person clase pojo

public class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

Y desea analizarlo en una matriz JSON o en un mapa de objetos Person. Debido al borrado de tipos, no puede construir clases de List<Person> y Map<String, Person> en tiempo de ejecución directamente (y, por lo tanto, usarlas para deserializar JSON) . Para superar esta limitación, jackson proporciona dos enfoques: TypeFactory y TypeReference .

TypeFactory

El enfoque adoptado aquí es utilizar una fábrica (y su función de utilidad estática) para crear su tipo para usted. Los parámetros que toma son la colección que desea utilizar (lista, conjunto, etc.) y la clase que desea almacenar en esa colección.

TypeReference

El enfoque de referencia de tipo parece más sencillo porque le ahorra un poco de escritura y se ve más limpio. TypeReference acepta un parámetro de tipo, donde pasa el tipo de List<Person> deseado List<Person> . Simplemente crea una instancia de este objeto TypeReference y lo utiliza como su contenedor de tipo.

Ahora veamos cómo deserializar su JSON en un objeto Java. Si su JSON está formateado como una matriz, puede deserializarlo como una Lista. Si hay una estructura anidada más compleja, deseará deserializar a un mapa. Veremos ejemplos de ambos.

Deserialización de matriz JSON

String jsonString = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]"

Enfoque de TypeFactory

CollectionType listType = 
    factory.constructCollectionType(List.class, Person.class);
List<Preson> list = mapper.readValue(jsonString, listType);

Tipo de enfoque de referencia

TypeReference<Person> listType = new TypeReference<List<Person>>() {};
List<Person> list = mapper.readValue(jsonString, listType);

Deserialización del mapa JSON

String jsonString = "{\"0\": {\"name\": \"Alice\"}, \"1\": {\"name\": \"Bob\"}}"

Enfoque de TypeFactory

CollectionType mapType = 
    factory.constructMapLikeType(Map.class, String.class, Person.class);
List<Person> list = mapper.readValue(jsonString, mapType);

Tipo de enfoque de referencia

TypeReference<Person> mapType = new TypeReference<Map<String, Person>>() {};
Map<String, Person> list = mapper.readValue(jsonString, mapType);

Detalles

Declaración de importación utilizada:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;

Instancias utilizadas:

ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = mapper.getTypeFactory();

Nota

Si TypeReference enfoque de TypeReference puede verse mejor, tiene varios inconvenientes:

  1. TypeReference debe ser instanciada usando una clase anónima
  2. Usted debe proporcionar una explicación genérica.

Si no lo hace, puede provocar la pérdida de un argumento de tipo genérico que llevará a un error de deserialización.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow