HOWTO · Java
Convertir cadena en objeto JSON en Java
Este tutorial explica cómo convertir una cadena en un objeto json en java
En esta página
Para utilizar texto JSON en Java, analízalo con una biblioteca JSON. El análisis produce un árbol JSON específico de la biblioteca que puedes inspeccionar dinámicamente; asignar el texto a una clase Java, en cambio, produce un objeto tipado. Las tres opciones aquí son org.json, Gson y Jackson. Cada una necesita su propia dependencia. Elige un árbol cuando quieras inspeccionar los campos dinámicamente, o asigna el texto a una clase Java cuando la forma de los datos sea conocida y los campos tipados sean útiles.
Usar JSONObject para convertir una cadena en un objeto JSON en Java
La biblioteca JSON-java (org.json) analiza una cadena de objeto con new JSONObject(json). Para Maven, añade org.json:json:20201115 dentro del elemento <dependencies> de pom.xml. El constructor devuelve un JSONObject; lee los miembros de cadena y enteros con getString("name") y getInt("age"). Estas llamadas devuelven valores Java, mientras que el JSONObject sigue siendo la representación del objeto JSON en memoria de la biblioteca. Recupera los miembros por clave, porque el orden de los miembros de un objeto no es una propiedad semántica fiable.
El siguiente ejemplo completo utiliza new JSONObject(json) para analizar el ejemplo compartido {"name":"John","age":30}, lee e imprime ambos campos y maneja JSONException:
import org.json.JSONException;
import org.json.JSONObject;
public class StringToJsonObjectWithJsonOrg {
public static void main(String[] args) {
String json = "{\"name\":\"John\",\"age\":30}";
try {
JSONObject object = new JSONObject(json);
System.out.println("name: " + object.getString("name"));
System.out.println("age: " + object.getInt("age"));
} catch (JSONException e) {
System.err.println("Invalid JSON: " + e.getMessage());
}
}
}
name: John
age: 30
A modo de comparación, el siguiente ejemplo, que solo utiliza el JDK, también extrae los dos campos del ejemplo e imprime sus valores, utilizando únicamente una expresión regular. Está limitado a esta forma de entrada plana; no analiza ni valida JSON general. La entrada se declara en main, así que guarda el fragmento como StringToJsonObject.java y compílalo con un JDK.
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StringToJsonObject {
public static void main(String[] args) {
String json = "{\"name\":\"John\",\"age\":30}";
Pattern field = Pattern.compile("\\\"(name|age)\\\"\\s*:\\s*(?:\\\"([^\\\"]*)\\\"|(\\d+))");
Matcher matcher = field.matcher(json);
Map<String, String> values = new LinkedHashMap<>();
while (matcher.find()) {
String value = matcher.group(2) != null ? matcher.group(2) : matcher.group(3);
values.put(matcher.group(1), value);
}
System.out.println("name: " + values.get("name"));
System.out.println("age: " + values.get("age"));
}
}
name: John
age: 30
Esta expresión regular solo cubre los miembros de cadena y enteros mostrados. No valida la sintaxis JSON ni maneja correctamente comillas escapadas, estructuras anidadas, matrices u otros valores JSON. Utiliza JSONObject u otro analizador para la entrada de la aplicación, y comprueba que los miembros requeridos existan y tengan los tipos esperados antes de leerlos. Captura JSONException alrededor del análisis y de las lecturas tipadas para que quien llama pueda informar de un fallo de análisis o de acceso a un valor, o recuperarse de él.
Usar Google Gson para convertir una cadena en un objeto JSON en Java
Gson puede analizar texto en un árbol JSON o asignarlo directamente a una clase Java. Para inspeccionar campos sin definir una clase, añade com.google.code.gson:gson:2.8.6 dentro del elemento <dependencies> de Maven. Analiza un árbol con JsonParser.parseString(json).getAsJsonObject() y, a continuación, lee los miembros con object.get("name").getAsString() y object.get("age").getAsInt(). Esto devuelve un árbol JsonObject, no una instancia de una clase de dominio.
El siguiente ejemplo completo analiza el mismo ejemplo en un JsonObject, lee e imprime ambos campos y maneja los errores de análisis:
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
public class StringToJsonObjectWithGson {
public static void main(String[] args) {
String json = "{\"name\":\"John\",\"age\":30}";
try {
JsonObject object = JsonParser.parseString(json).getAsJsonObject();
System.out.println("name: " + object.get("name").getAsString());
System.out.println("age: " + object.get("age").getAsInt());
} catch (JsonParseException | IllegalStateException e) {
System.err.println("Invalid JSON: " + e.getMessage());
}
}
}
name: John
age: 30
Si los datos tienen una forma conocida y los campos tipados son útiles, define una clase User con los campos String name e int age y, a continuación, llama a new Gson().fromJson(json, User.class) para producir un User. Para serializar esa instancia de nuevo a texto JSON, llama a new Gson().toJson(user). GsonBuilder.setPrettyPrinting() configura el formato durante la serialización; no cambia el árbol analizado ni el valor Java. Maneja JsonParseException para los problemas de análisis y, después, valida los campos requeridos, porque un JSON válido puede aun así omitir datos que tu programa necesita.
Usar Jackson para convertir una cadena en un objeto JSON
El modelo de árbol de Jackson es útil cuando necesitas seleccionar campos dinámicamente. Añade com.fasterxml.jackson.core:jackson-databind:2.11.3 dentro del elemento <dependencies> de Maven. El artefacto jackson-databind proporciona la API de árbol ObjectMapper e incluye Jackson core como dependencia. Llama a new ObjectMapper().readTree(json) para analizar el texto en un JsonNode, la representación de árbol JSON de Jackson. Lee los valores del ejemplo con node.get("name").asText() y node.get("age").asInt(); utiliza el miembro correspondiente para cada valor.
El siguiente ejemplo completo utiliza ObjectMapper.readTree(json), lee e imprime ambos campos y maneja la excepción comprobada JsonProcessingException:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class StringToJsonObjectWithJackson {
public static void main(String[] args) {
String json = "{\"name\":\"John\",\"age\":30}";
try {
JsonNode node = new ObjectMapper().readTree(json);
System.out.println("name: " + node.get("name").asText());
System.out.println("age: " + node.get("age").asInt());
} catch (JsonProcessingException e) {
System.err.println("Invalid JSON: " + e.getMessage());
}
}
}
name: John
age: 30
readTree puede lanzar la excepción comprobada JsonProcessingException, así que manéjala donde se produzca el análisis. Comprueba también que cada nodo solicitado exista y tenga el tipo esperado antes de utilizar accesores de conveniencia como asText() o asInt(). En caso contrario, un miembro ausente o de otro tipo puede producir un valor que no sea adecuado para la aplicación, incluso cuando el propio documento JSON se haya analizado correctamente.
Las tres bibliotecas analizan texto JSON, pero sus tipos de árbol y sus API difieren: JSONObject, JsonObject y JsonNode. Un documento mal formado falla durante el análisis, y la clase y el mensaje de la excepción dependen de la biblioteca elegida. El análisis por sí solo no garantiza que los campos requeridos estén presentes ni que los valores tengan los tipos que tu aplicación espera, así que valídalos antes de utilizarlos. El ejemplo de expresión regular que solo utiliza el JDK está limitado al ejemplo plano mostrado; utiliza una de las API de biblioteca con dependencia para la entrada JSON general.