Java Language
JSON en Java
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:
-
TypeReference
debe ser instanciada usando una clase anónima - 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.