Cómo analizar JSON en Java

1049

Tengo el siguiente texto JSON. ¿Cómo puedo analizarlo para obtener los valores de pageName, pagePic, post_id, etc.?

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}
Muhammad Maqsoodur Rehman
fuente
77
Las bibliotecas JSON integradas en Java son la forma rápida de hacerlo, pero en mi experiencia GSON es la mejor biblioteca para analizar un JSON en un POJO sin problemas.
Iman Akbari
16
Esta es la primera pregunta altamente votada y protegida cuyas respuestas encontré más confusas
Riyafa Abdul Hameed
66
@JaysonMinard estuvo de acuerdo. Pidió la intervención mod. Esto debería estar cerrado realmente. Inicialmente supuse (erróneamente) que no podía hacerlo mientras la pregunta estaba protegida, así que la desprotegí e hice lo mío. Vuelva a protegerlo ahora para evitar respuestas de bajas repeticiones y cosas por el estilo, mientras espera un mod.
Mena
44
"Esta pregunta no muestra ningún esfuerzo de investigación" - Información sobre herramientas de botón de voto negativo
Jean-François Corbett
66
Esta pregunta se está discutiendo en Meta .
Mark Amery

Respuestas:

755

La biblioteca org.json es fácil de usar. Código de ejemplo a continuación:

import org.json.*;

String jsonString = ... ; //assign your JSON String here
JSONObject obj = new JSONObject(jsonString);
String pageName = obj.getJSONObject("pageInfo").getString("pageName");

JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
    String post_id = arr.getJSONObject(i).getString("post_id");
    ......
}

Puede encontrar más ejemplos de: Parse JSON en Java

Jar descargable: http://mvnrepository.com/artifact/org.json/json

usuario1931858
fuente
15
Estoy de acuerdo con @StaxMan. Acabo de probar org.json y es terriblemente engorroso. Realmente no juega con los tipos estándar de Java Collection, por ejemplo.
Ken Williams
77
@StaxMan Elegiría org.jsonsobre otras bibliotecas para el análisis JSON simple sin siquiera mirar. Es la biblioteca de referencia que Douglas Crockford (el descubridor de JSON) creó.
Omar Al-Ithawi
31
@OmarIthawi eso es una tontería. Es una prueba de concepto con API incómoda, implementación ineficiente. Creo que es mejor considerar las bibliotecas por sus propios méritos, en lugar de tratar de deducir la calidad de la visibilidad de sus autores: Doug ha logrado muchas cosas, pero eso no cambia realmente las cualidades de la biblioteca en particular. Hace 10 años era el único juego en la ciudad, pero desde entonces ha habido un progreso muy positivo. Es como Struts of json libs.
StaxMan
12
org.json se encuentra entre las peores bibliotecas json. Uno debe mirar el conjunto de características y el rendimiento de las bibliotecas json disponibles antes de elegir. Aquí hay un punto de referencia que hice comparando jackson, gson, org.json, genson usando JMH: github.com/fabienrenaud/java-json-benchmark . Jackson es el claro ganador aquí.
fabien
44
La licencia no incluye ninguna licencia de código abierto comúnmente utilizada, y también posee derechos de autor.
Christian Vielma
537

Por el bien del ejemplo, supongamos que tiene una clase Personcon solo un name.

private class Person {
    public String name;

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

Google GSON ( Maven )

Mi favorito personal en cuanto a la gran serialización / deserialización JSON de objetos.

Gson g = new Gson();

Person person = g.fromJson("{\"name\": \"John\"}", Person.class);
System.out.println(person.name); //John

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

Actualizar

Si desea obtener un solo atributo, también puede hacerlo fácilmente con la biblioteca de Google:

JsonObject jsonObject = new JsonParser().parse("{\"name\": \"John\"}").getAsJsonObject();

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

Org.JSON ( Maven )

Si no necesita la deserialización de objetos, sino simplemente obtener un atributo, puede probar org.json (¡ o consulte el ejemplo de GSON anterior! )

JSONObject obj = new JSONObject("{\"name\": \"John\"}");

System.out.println(obj.getString("name")); //John

Jackson ( Maven )

ObjectMapper mapper = new ObjectMapper();
Person user = mapper.readValue("{\"name\": \"John\"}", Person.class);

System.out.println(user.name); //John
SDekov
fuente
16
Buena respuesta. Una sugerencia para una mejora menor: tanto GSON como Jackson también admiten el uso de la representación de árbol JSON (para Jackson, estos son JsonNodes, GSON tiene algo similar). Podría ser bueno mostrar fragmentos, ya que es similar a la única forma que ofrece org.json.
StaxMan
Otras dos bibliotecas que vale la pena mencionar (en aras de la integridad): json-simple y JSONP de Oracle
jake stayman
3
@NeonWarge, ¿por qué? Me parece que esta respuesta asume que uno ya ha definido una clase Java que contiene exactamente los mismos campos que la cadena JSON, nada menos y nada más. Esta es una suposición bastante fuerte.
Andrea Lazzarotto
1
json-simple y jraclep de Oracle funcionan terriblemente: github.com/fabienrenaud/java-json-benchmark Para el rendimiento, elija jackson o dsljson.
fabien
¡GSON no admite el filtrado dinámico de campos en niveles que no sean root!
Gangnus
102
  1. Si se quiere crear un objeto Java desde JSON y viceversa, use tarros de terceros GSON o JACKSON, etc.

    //from object to JSON 
    Gson gson = new Gson();
    gson.toJson(yourObject);
    
    // from JSON to object 
    yourObject o = gson.fromJson(JSONString,yourObject.class);
  2. Pero si uno solo quiere analizar una cadena JSON y obtener algunos valores, (O crear una cadena JSON desde cero para enviarla por cable) simplemente use el jar JaveEE que contiene JsonReader, JsonArray, JsonObject, etc. Es posible que desee descargar la implementación de ese especificaciones como javax.json. Con estos dos frascos puedo analizar el json y usar los valores.

    Estas API realmente siguen el modelo de análisis DOM / SAX de XML.

    Response response = request.get(); // REST call 
        JsonReader jsonReader = Json.createReader(new StringReader(response.readEntity(String.class)));
        JsonArray jsonArray = jsonReader.readArray();
        ListIterator l = jsonArray.listIterator();
        while ( l.hasNext() ) {
              JsonObject j = (JsonObject)l.next();
              JsonObject ciAttr = j.getJsonObject("ciAttributes");
mediocre
fuente
44
@nondescript Si tuviera que adivinar, diría que fue rechazado porque no responde a la pregunta original del cartel: "¿Cuál es el código requerido?" Las respuestas que se votaron proporcionaron fragmentos de código.
jewbix.cube
44
Nota: Jackson y GSON son compatibles con el estilo de árbol y / o el enlace de Mapas / Listas, por lo que no es necesario usar el paquete Java EE (javax.json). javax.json tiene poco que ofrecer más allá de Jackson o GSON.
StaxMan
Sugiero agregar un enlace a la biblioteca JavaEE.
Basil Bourque
72

analizador quick-json es muy sencillo, flexible, muy rápido y personalizable. Intentalo

caracteristicas:

  • Cumple con la especificación JSON (RFC4627)
  • Analizador JSON de alto rendimiento
  • Admite el enfoque de análisis flexible / configurable
  • Validación configurable de pares clave / valor de cualquier jerarquía JSON
  • Fácil de usar # Tamaño muy pequeño
  • Genera excepciones amigables para el desarrollador y fáciles de rastrear
  • Soporte de validación personalizada conectable: las claves / valores se pueden validar configurando validadores personalizados cuando se encuentren
  • Validación y no validación del analizador
  • Soporte para dos tipos de configuración (JSON / XML) para usar el analizador de validación JSON rápido
  • Requiere JDK 1.5
  • No depende de bibliotecas externas.
  • Soporte para la generación JSON a través de la serialización de objetos.
  • Soporte para la selección del tipo de colección durante el proceso de análisis

Se puede usar así:

JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson(jsonString);
rputta
fuente
3
¿Hay un javadoc disponible?
jboi
24
Este paquete no puede manejar valores vacíos al analizar. Por ejemplo: ... "description": "" ... lanza una excepción
Ivan
66
He solucionado este problema (y muchos otros) en code.google.com/p/quick-json/issues/detail?id=11 Espero que el autor se tome el tiempo para solucionarlo en el lanzamiento oficial.
noamik
8
De las características enumeradas, nada es único en comparación con otras opciones, y la afirmación de alto rendimiento no es compatible con nada; a diferencia de las bibliotecas más maduras (Gson, Jackson, Genson, Boon) que se incluyen en puntos de referencia como github.com/eishay/jvm-serializers , github.com/novoj/JavaJsonPerformanceTest o developer.com/lang/jscript/… - I No he visto esta biblioteca incluida en las pruebas, o menciona que se usa ampliamente.
StaxMan
26
Este proyecto parece estar muerto y parece que ya no está alojado en el repositorio central de Maven.
8bitjunkie
40

Podrías usar Google Gson .

Con esta biblioteca, solo necesita crear un modelo con la misma estructura JSON. Luego, el modelo se completa automáticamente. Debe llamar a sus variables como sus teclas JSON, o usarlas @SerializedNamesi desea usar nombres diferentes.

JSON

De tu ejemplo:

{
    "pageInfo": {
        "pageName": "abc",
        "pagePic": "http://example.com/content.jpg"
    }
    "posts": [
        {
            "post_id": "123456789012_123456789012",
            "actor_id": "1234567890",
            "picOfPersonWhoPosted": "http://example.com/photo.jpg",
            "nameOfPersonWhoPosted": "Jane Doe",
            "message": "Sounds cool. Can't wait to see it!",
            "likesCount": "2",
            "comments": [],
            "timeOfPost": "1234567890"
        }
    ]
}

Modelo

class MyModel {

    private PageInfo pageInfo;
    private ArrayList<Post> posts = new ArrayList<>();
}

class PageInfo {

    private String pageName;
    private String pagePic;
}

class Post {

    private String post_id;

    @SerializedName("actor_id") // <- example SerializedName
    private String actorId;

    private String picOfPersonWhoPosted;
    private String nameOfPersonWhoPosted;
    private String message;
    private String likesCount;
    private ArrayList<String> comments;
    private String timeOfPost;
}

Analizando

Ahora puedes analizar usando la biblioteca Gson:

MyModel model = gson.fromJson(jsonString, MyModel.class);

Importar Gradle

Recuerde importar la biblioteca en el archivo Gradle de la aplicación

implementation 'com.google.code.gson:gson:2.8.6' // or earlier versions

Generación automática de modelos.

Puede generar modelos desde JSON automáticamente utilizando herramientas en línea como esta .

lubilis
fuente
38

Casi todas las respuestas dadas requieren una deserialización completa del JSON en un objeto Java antes de acceder al valor en la propiedad de interés. Otra alternativa, que no sigue esta ruta es usar JsonPATH, que es como XPath para JSON y permite atravesar objetos JSON.

Es una especificación y la buena gente de JayWay ha creado una implementación de Java para la especificación que puede encontrar aquí: https://github.com/jayway/JsonPath

Básicamente, para usarlo, agréguelo a su proyecto, por ejemplo:

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>${version}</version>
</dependency>

y para usar:

String pageName = JsonPath.read(yourJsonString, "$.pageInfo.pageName");
String pagePic = JsonPath.read(yourJsonString, "$.pageInfo.pagePic");
String post_id = JsonPath.read(yourJsonString, "$.pagePosts[0].post_id");

etc ...

Consulte la página de especificaciones de JsonPath para obtener más información sobre las otras formas de cruzar JSON.

dade
fuente
Esta es una muy buena biblioteca, especialmente para leer y actualizar JSON, pero tenga cuidado con algunos problemas conocidos sobre esta biblioteca. Ver [1]: github.com/json-path/JsonPath/issues/272 [2]: github.com/json-path/JsonPath/issues/375
papigee
38

A - Explicación

Puede usar las bibliotecas de Jackson , para vincular la cadena JSON en instancias de POJO ( Objeto Java antiguo simple ). POJO es simplemente una clase con solo campos privados y métodos públicos getter / setter. Jackson va a atravesar los métodos (usando la reflexión ), y asigna el objeto JSON a la instancia de POJO a medida que los nombres de campo de la clase se ajustan a los nombres de campo del objeto JSON.

En su objeto JSON, que en realidad es un objeto compuesto , el objeto principal consta de dos subobjetos. Entonces, nuestras clases POJO deben tener la misma jerarquía. Llamaré a todo el objeto JSON como objeto de página . El objeto de página consta de un objeto PageInfo y una matriz de objetos Post .

Entonces tenemos que crear tres clases POJO diferentes;

  • Page Class, un compuesto de PageInfo Class y una matriz de Post Instancias
  • PageInfo Class
  • Clase de publicaciones

El único paquete que he usado es Jackson ObjectMapper, lo que hacemos es vincular datos;

com.fasterxml.jackson.databind.ObjectMapper

Las dependencias requeridas, los archivos jar se enumeran a continuación;

  • jackson-core-2.5.1.jar
  • jackson-databind-2.5.1.jar
  • jackson-annotations-2.5.0.jar

Aquí está el código requerido;

B - Clase principal POJO: Página

package com.levo.jsonex.model;

public class Page {

    private PageInfo pageInfo;
    private Post[] posts;

    public PageInfo getPageInfo() {
        return pageInfo;
    }

    public void setPageInfo(PageInfo pageInfo) {
        this.pageInfo = pageInfo;
    }

    public Post[] getPosts() {
        return posts;
    }

    public void setPosts(Post[] posts) {
        this.posts = posts;
    }

}

C - Clase POJO para niños: PageInfo

package com.levo.jsonex.model;

public class PageInfo {

    private String pageName;
    private String pagePic;

    public String getPageName() {
        return pageName;
    }

    public void setPageName(String pageName) {
        this.pageName = pageName;
    }

    public String getPagePic() {
        return pagePic;
    }

    public void setPagePic(String pagePic) {
        this.pagePic = pagePic;
    }

}

D - Clase POJO para niños: Publicar

package com.levo.jsonex.model;

public class Post {

    private String post_id;
    private String actor_id;
    private String picOfPersonWhoPosted;
    private String nameOfPersonWhoPosted;
    private String message;
    private int likesCount;
    private String[] comments;
    private int timeOfPost;

    public String getPost_id() {
        return post_id;
    }

    public void setPost_id(String post_id) {
        this.post_id = post_id;
    }

    public String getActor_id() {
        return actor_id;
    }

    public void setActor_id(String actor_id) {
        this.actor_id = actor_id;
    }

    public String getPicOfPersonWhoPosted() {
        return picOfPersonWhoPosted;
    }

    public void setPicOfPersonWhoPosted(String picOfPersonWhoPosted) {
        this.picOfPersonWhoPosted = picOfPersonWhoPosted;
    }

    public String getNameOfPersonWhoPosted() {
        return nameOfPersonWhoPosted;
    }

    public void setNameOfPersonWhoPosted(String nameOfPersonWhoPosted) {
        this.nameOfPersonWhoPosted = nameOfPersonWhoPosted;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getLikesCount() {
        return likesCount;
    }

    public void setLikesCount(int likesCount) {
        this.likesCount = likesCount;
    }

    public String[] getComments() {
        return comments;
    }

    public void setComments(String[] comments) {
        this.comments = comments;
    }

    public int getTimeOfPost() {
        return timeOfPost;
    }

    public void setTimeOfPost(int timeOfPost) {
        this.timeOfPost = timeOfPost;
    }

}

E - Archivo JSON de muestra: sampleJSONFile.json

Acabo de copiar su muestra JSON en este archivo y ponerlo en la carpeta del proyecto.

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

F - Código de demostración

package com.levo.jsonex;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.levo.jsonex.model.Page;
import com.levo.jsonex.model.PageInfo;
import com.levo.jsonex.model.Post;

public class JSONDemo {

    public static void main(String[] args) {
        ObjectMapper objectMapper = new ObjectMapper();

        try {
            Page page = objectMapper.readValue(new File("sampleJSONFile.json"), Page.class);

            printParsedObject(page);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void printParsedObject(Page page) {
        printPageInfo(page.getPageInfo());
        System.out.println();
        printPosts(page.getPosts());
    }

    private static void printPageInfo(PageInfo pageInfo) {
        System.out.println("Page Info;");
        System.out.println("**********");
        System.out.println("\tPage Name : " + pageInfo.getPageName());
        System.out.println("\tPage Pic  : " + pageInfo.getPagePic());
    }

    private static void printPosts(Post[] posts) {
        System.out.println("Page Posts;");
        System.out.println("**********");
        for(Post post : posts) {
            printPost(post);
        }
    }

    private static void printPost(Post post) {
        System.out.println("\tPost Id                   : " + post.getPost_id());
        System.out.println("\tActor Id                  : " + post.getActor_id());
        System.out.println("\tPic Of Person Who Posted  : " + post.getPicOfPersonWhoPosted());
        System.out.println("\tName Of Person Who Posted : " + post.getNameOfPersonWhoPosted());
        System.out.println("\tMessage                   : " + post.getMessage());
        System.out.println("\tLikes Count               : " + post.getLikesCount());
        System.out.println("\tComments                  : " + Arrays.toString(post.getComments()));
        System.out.println("\tTime Of Post              : " + post.getTimeOfPost());
    }

}

G - Salida de demostración

Page Info;
****(*****
    Page Name : abc
    Page Pic  : http://example.com/content.jpg
Page Posts;
**********
    Post Id                   : 123456789012_123456789012
    Actor Id                  : 1234567890
    Pic Of Person Who Posted  : http://example.com/photo.jpg
    Name Of Person Who Posted : Jane Doe
    Message                   : Sounds cool. Can't wait to see it!
    Likes Count               : 2
    Comments                  : []
    Time Of Post              : 1234567890
Levent Divilioglu
fuente
26

Use minimal-json que es muy rápido y fácil de usar. Puede analizar desde String obj y Stream.

Data de muestra:

{
  "order": 4711,
  "items": [
    {
      "name": "NE555 Timer IC",
      "cat-id": "645723",
      "quantity": 10,
    },
    {
      "name": "LM358N OpAmp IC",
      "cat-id": "764525",
      "quantity": 2
    }
  ]
}

Analizando:

JsonObject object = Json.parse(input).asObject();
int orders = object.get("order").asInt();
JsonArray items = object.get("items").asArray();

Creando JSON:

JsonObject user = Json.object().add("name", "Sakib").add("age", 23);

Maven

<dependency>
  <groupId>com.eclipsesource.minimal-json</groupId>
  <artifactId>minimal-json</artifactId>
  <version>0.9.4</version>
</dependency>
Sakib Sami
fuente
¿Cómo se verá el pojo?
Jesse
Para Pojo usa gson. Esta biblioteca no es compatible.
Sakib Sami
22

Creo que la mejor práctica debería ser pasar por la API oficial de Java JSON que todavía están en progreso.

Giovanni Botta
fuente
77
Desde que respondí, comencé a usar Jackson y creo que es una de las mejores bibliotecas para la deserialización de JSON.
Giovanni Botta
2
¿Por qué reutilizan JSONP para significar algo diferente a JSON con Padding ? ...
Chris Wesseling
@ChrisWesseling ¿Qué quieres decir?
Giovanni Botta
"API de Java para procesamiento JSON (JSON-P)" es el título del documento al que se vincula. Y me confundió, porque sabía que JSONP significaba algo más.
Chris Wesseling
1
@ChrisWesseling oh, eso es confuso. Eso es lo que eligieron para la especificación. Sin embargo, como dije, iría directamente a Jackson.
Giovanni Botta
22

Como nadie lo mencionó todavía, aquí hay un comienzo de una solución usando Nashorn (JavaScript runtime parte de Java 8, pero obsoleto en Java 11).

Solución

private static final String EXTRACTOR_SCRIPT =
    "var fun = function(raw) { " +
    "var json = JSON.parse(raw); " +
    "return [json.pageInfo.pageName, json.pageInfo.pagePic, json.posts[0].post_id];};";

public void run() throws ScriptException, NoSuchMethodException {
    ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
    engine.eval(EXTRACTOR_SCRIPT);
    Invocable invocable = (Invocable) engine;
    JSObject result = (JSObject) invocable.invokeFunction("fun", JSON);
    result.values().forEach(e -> System.out.println(e));
}

Comparación de rendimiento

Escribí contenido JSON que contenía tres matrices de 20, 20 y 100 elementos respectivamente. Solo quiero obtener los 100 elementos de la tercera matriz. Utilizo la siguiente función de JavaScript para analizar y obtener mis entradas.

var fun = function(raw) {JSON.parse(raw).entries};

Ejecutar la llamada un millón de veces usando Nashorn toma 7.5 ~ 7.8 segundos

(JSObject) invocable.invokeFunction("fun", json);

org.json toma 20 ~ 21 segundos

new JSONObject(JSON).getJSONArray("entries");

Jackson toma 6.5 ~ 7 segundos

mapper.readValue(JSON, Entries.class).getEntries();

En este caso, Jackson funciona mejor que Nashorn, que funciona mucho mejor que org.json. Nashorn API es más difícil de usar que org.json's o Jackson's. Dependiendo de sus requisitos, Jackson y Nashorn pueden ser soluciones viables.

otonglet
fuente
1
¿Cuál es la unidad " ""? No pulgadas? ¿Son segundos? ¿Minutos?
Peter Mortensen
1
@PeterMortensen significa segundos. Como parece poco claro, lo cambiaré. Gracias por el comentario
otonglet
2
Desafortunadamente, Nashorn está en desuso en Java 11. JEP 335 .
Por Mildner
1
Sé que Nashorn está en desuso, pero me gustó esta respuesta porque no quería dependencias; sin embargo, tuve que reelaborar un poco el ejemplo:ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); engine.eval("var fun = function(raw) { return JSON.parse(raw); };"); Map<String, Object> json = (Map<String, Object>) ((Invocable) engine).invokeFunction("fun", jsonString);
kgibm
21

El siguiente ejemplo muestra cómo leer el texto en la pregunta, representada como la variable "jsonText". Esta solución utiliza la API Java EE7 javax.json (que se menciona en algunas de las otras respuestas). La razón por la que lo agregué como una respuesta separada es que el siguiente código muestra cómo acceder realmente a algunos de los valores que se muestran en la pregunta. Se necesitaría una implementación de la API javax.json para ejecutar este código. El paquete completo para cada una de las clases requeridas se incluyó ya que no quería declarar declaraciones de "importación".

javax.json.JsonReader jr = 
    javax.json.Json.createReader(new StringReader(jsonText));
javax.json.JsonObject jo = jr.readObject();

//Read the page info.
javax.json.JsonObject pageInfo = jo.getJsonObject("pageInfo");
System.out.println(pageInfo.getString("pageName"));

//Read the posts.
javax.json.JsonArray posts = jo.getJsonArray("posts");
//Read the first post.
javax.json.JsonObject post = posts.getJsonObject(0);
//Read the post_id field.
String postId = post.getString("post_id");

Ahora, antes de que alguien vaya y rechace esta respuesta porque no usa GSON, org.json, Jackson o cualquiera de los otros marcos de terceros disponibles, es un ejemplo de "código requerido" según la pregunta para analizar el texto proporcionado. Soy muy consciente de que la adhesión al estándar JSR 353 actual no se estaba considerando para JDK 9 y, como tal, la especificación JSR 353 debería tratarse de la misma manera que cualquier otra implementación de manejo de JSON de terceros.

justin.hughey
fuente
15

Esto me dejó alucinado con lo fácil que fue. Simplemente puede pasar una Stringretención de su JSON al constructor de un JSONObject en el paquete org.json predeterminado.

JSONArray rootOfPage =  new JSONArray(JSONString);

Hecho. Gotas de micrófono . Esto funciona con JSONObjectstambién. Después de eso, puede mirar a través de su jerarquía de Objectsusar los get()métodos en sus objetos.

brainmurphy1
fuente
13
El JSONArraytipo no es parte de la API J2SE JDK y no dice qué API o biblioteca de terceros proporciona este tipo.
Bobulous
2
No es que yo recomendaría usarlo, pero creo que esto se refiere al paquete "org.json" de json.org/java . Solía ​​usarse antes de que las buenas bibliotecas Java estuvieran disponibles, pero esto fue hace años (2008 o antes)
StaxMan
1
¿O brainmurphy1 significa JSONArray en Android?
Alexander Farber
12

Hay muchas bibliotecas JSON disponibles en Java.

Los más notorios son: Jackson, GSON, Genson, FastJson y org.json.

Por lo general, hay tres cosas que uno debe mirar para elegir cualquier biblioteca:

  1. Actuación
  2. Facilidad de uso (el código es simple de escribir y legible): eso va con las características.
  3. Para aplicaciones móviles: dependencia / tamaño de jar

Específicamente para las bibliotecas JSON (y cualquier biblioteca de serialización / deserialización), el enlace de datos también suele ser de interés ya que elimina la necesidad de escribir código de placa de caldera para empacar / desempaquetar los datos.

Para 1, vea este punto de referencia: https://github.com/fabienrenaud/java-json-benchmark que hice usando JMH que compara (jackson, gson, genson, fastjson, org.json, jsonp) el rendimiento de serializadores y deserializadores usando stream y API de enlace de datos. Para 2, puede encontrar numerosos ejemplos en Internet. El punto de referencia anterior también se puede utilizar como fuente de ejemplos ...

Conclusión rápida del punto de referencia: Jackson se desempeña entre 5 y 6 veces mejor que org.json y más del doble que GSON.

Para su ejemplo particular, el siguiente código decodifica su json con jackson:

public class MyObj {

    private PageInfo pageInfo;
    private List<Post> posts;

    static final class PageInfo {
        private String pageName;
        private String pagePic;
    }

    static final class Post {
        private String post_id;
        @JsonProperty("actor_id");
        private String actorId;
        @JsonProperty("picOfPersonWhoPosted")
        private String pictureOfPoster;
        @JsonProperty("nameOfPersonWhoPosted")
        private String nameOfPoster;
        private String likesCount;
        private List<String> comments;
        private String timeOfPost;
    }

    private static final ObjectMapper JACKSON = new ObjectMapper();
    public static void main(String[] args) throws IOException {
        MyObj o = JACKSON.readValue(args[0], MyObj.class); // assumes args[0] contains your json payload provided in your question.
    }
}

Hazme saber si tienes alguna pregunta.

fabien
fuente
11

Además de otras respuestas, recomiendo este servicio en línea de código abierto jsonschema2pojo.org para generar rápidamente clases Java a partir de esquemas json o json para GSON, Jackson 1.xo Jackson 2.x. Por ejemplo, si tienes:

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    }
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": 1234567890,
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": 2,
              "comments": [],
              "timeOfPost": 1234567890
         }
    ]
}

El jsonschema2pojo.org para GSON generó:

@Generated("org.jsonschema2pojo")
public class Container {
    @SerializedName("pageInfo")
    @Expose
    public PageInfo pageInfo;
    @SerializedName("posts")
    @Expose
    public List<Post> posts = new ArrayList<Post>();
}

@Generated("org.jsonschema2pojo")
public class PageInfo {
    @SerializedName("pageName")
    @Expose
    public String pageName;
    @SerializedName("pagePic")
    @Expose
    public String pagePic;
}

@Generated("org.jsonschema2pojo")
public class Post {
    @SerializedName("post_id")
    @Expose
    public String postId;
    @SerializedName("actor_id")
    @Expose
    public long actorId;
    @SerializedName("picOfPersonWhoPosted")
    @Expose
    public String picOfPersonWhoPosted;
    @SerializedName("nameOfPersonWhoPosted")
    @Expose
    public String nameOfPersonWhoPosted;
    @SerializedName("message")
    @Expose
    public String message;
    @SerializedName("likesCount")
    @Expose
    public long likesCount;
    @SerializedName("comments")
    @Expose
    public List<Object> comments = new ArrayList<Object>();
    @SerializedName("timeOfPost")
    @Expose
    public long timeOfPost;
}
Viacheslav Vedenin
fuente
9

Si tiene alguna clase de Java (digamos Mensaje) que representa la cadena JSON (jsonString), puede usar la biblioteca Jackson JSON con:

Message message= new ObjectMapper().readValue(jsonString, Message.class);

y desde el objeto de mensaje puede obtener cualquiera de sus atributos.

Shailendra Singh
fuente
9

Gson es fácil de aprender e implementar, lo que necesitamos saber es seguir dos métodos

  • toJson () - Convertir objeto Java a formato JSON

  • fromJson () - Convierte JSON en objeto Java

``

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import com.google.gson.Gson;

public class GsonExample {
    public static void main(String[] args) {

    Gson gson = new Gson();

    try {

        BufferedReader br = new BufferedReader(
            new FileReader("c:\\file.json"));

        //convert the json string back to object
        DataObject obj = gson.fromJson(br, DataObject.class);

        System.out.println(obj);

    } catch (IOException e) {
        e.printStackTrace();
    }

    }
}

``

Venkat
fuente
Para obtener un conocimiento completo sobre Gson, consulte los enlaces a continuación. github.com/google/gson/blob/master/UserGuide.md
venkat
9

Hay muchas bibliotecas de código abierto presentes para analizar el contenido JSON en un objeto o simplemente para leer los valores JSON. Su requisito es solo leer valores y analizarlos en un objeto personalizado. Entonces, la biblioteca org.json es suficiente en su caso.

Use la biblioteca org.json para analizarla y crear JsonObject:

JSONObject jsonObj = new JSONObject(<jsonStr>);

Ahora, use este objeto para obtener sus valores:

String id = jsonObj.getString("pageInfo");

Puedes ver un ejemplo completo aquí:

Cómo analizar JSON en Java

lalitbhagtani
fuente
Parece que todas sus respuestas contienen un enlace a ese sitio. Si es spam, deténgase. Si no es así, disculpe la confusión, pero no creo que sea necesario publicar un enlace en todas sus respuestas.
Donald Duck
1
Es difícil dar una respuesta, donde puedes explicar todos los escenarios. Como en este caso, cómo leer una matriz json o varios objetos json. Incluso si lo hago, la respuesta sería muy larga y la persona podría confundirse. Así que les doy un enlace donde se da la explicación adecuada, con el ejemplo adecuado. Puede elegir visitar o puede usar solo mi explicación.
lalitbhagtani
1
Me parece que el enlace que ha proporcionado solo muestra cómo leer JSON. ¿Dónde puedo encontrar información sobre cómo JSON también?
Lampros Tzanetos
Lo siento, pero no entendí tu pregunta: - "sobre cómo JSON también"
lalitbhagtani
7

Por favor haz algo como esto:

JSONParser jsonParser = new JSONParser();
JSONObject obj = (JSONObject) jsonParser.parse(contentString);
String product = (String) jsonObject.get("productId");
Sreekanth
fuente
10
Er, ¿qué biblioteca es esta?
Stewart
2
Creo que está usando org.json.simple
Lasitha Yapa
7

Puede usar la Biblioteca Gson para analizar la cadena JSON.

Gson gson = new Gson();
JsonObject jsonObject = gson.fromJson(jsonAsString, JsonObject.class);

String pageName = jsonObject.getAsJsonObject("pageInfo").get("pageName").getAsString();
String pagePic = jsonObject.getAsJsonObject("pageInfo").get("pagePic").getAsString();
String postId = jsonObject.getAsJsonArray("posts").get(0).getAsJsonObject().get("post_id").getAsString();

También puede recorrer la matriz "posts" de la siguiente manera:

JsonArray posts = jsonObject.getAsJsonArray("posts");
for (JsonElement post : posts) {
  String postId = post.getAsJsonObject().get("post_id").getAsString();
  //do something
}
LittleBigUllah
fuente
5
{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    },
    "posts": [
         {
              "post_id": "123456789012_123456789012",
              "actor_id": "1234567890",
              "picOfPersonWhoPosted": "http://example.com/photo.jpg",
              "nameOfPersonWhoPosted": "Jane Doe",
              "message": "Sounds cool. Can't wait to see it!",
              "likesCount": "2",
              "comments": [],
              "timeOfPost": "1234567890"
         }
    ]
}

Java code :

JSONObject obj = new JSONObject(responsejsonobj);
String pageName = obj.getJSONObject("pageInfo").getString("pageName");

JSONArray arr = obj.getJSONArray("posts");
for (int i = 0; i < arr.length(); i++)
{
    String post_id = arr.getJSONObject(i).getString("post_id");
    ......etc
}
LReddy
fuente
99
Explique su respuesta ya que las respuestas de solo código ayudan a otros mucho menos que el código bien documentado. Ver "dale un pescado a un hombre y lo alimentarás por un día; enséñale a pescar y lo alimentarás toda la vida" .
Wai Ha Lee
Sería bueno mencionar que esto es para 'org.json' lib. Sin embargo, no creo que esta sea una buena manera de hacerlo, ya que es muy detallado y la biblioteca 'org.json' en sí misma es obsoleta (API lenta y engorrosa). Hay mejores opciones: GSON, Jackson, Boon, Genson para usar.
StaxMan
5

Lea la siguiente publicación de blog, JSON en Java .

Esta publicación es un poco antigua, pero aun así quiero responder tu pregunta.

Paso 1: crea una clase POJO de tus datos.

Paso 2: ahora crea un objeto usando JSON.

Employee employee = null;
ObjectMapper mapper = new ObjectMapper();
try{
    employee =  mapper.readValue(newFile("/home/sumit/employee.json"), Employee.class);
} 
catch (JsonGenerationException e){
    e.printStackTrace();
}

Para mayor referencia, puede consultar el siguiente enlace .

sumit kumar
fuente
4

Las respuestas principales en esta página usan ejemplos demasiado simples como objetos con una propiedad (por ejemplo, {nombre: valor}). Creo que ese ejemplo simple pero real puede ayudar a alguien.

Así que este es el JSON devuelto por la API de Google Translate:

{
  "data": 
     {
        "translations": 
          [
            {
              "translatedText": "Arbeit"
             }
          ]
     }
}

Quiero recuperar el valor del atributo "traducirTexto", por ejemplo, "Arbeit" usando Gson de Google.

Dos posibles enfoques:

  1. Recupere solo un atributo necesario

    String json  = callToTranslateApi("work", "de");
    JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
    return jsonObject.get("data").getAsJsonObject()
            .get("translations").getAsJsonArray()
            .get(0).getAsJsonObject()
            .get("translatedText").getAsString();
  2. Crear objeto Java desde JSON

    class ApiResponse {
        Data data;      
        class Data {
            Translation[] translations;         
            class Translation {
                String translatedText;
            }
         }
     }

    ...

     Gson g = new Gson();
     String json =callToTranslateApi("work", "de");
     ApiResponse response = g.fromJson(json, ApiResponse.class);
     return response.data.translations[0].translatedText;
yurin
fuente
4

Primero debes seleccionar una biblioteca de implementación para hacer eso.

La API de Java para el procesamiento JSON (JSR 353) proporciona API portátiles para analizar, generar, transformar y consultar JSON utilizando el modelo de objetos y las API de transmisión.

La implementación de referencia está aquí: https://jsonp.java.net/

Aquí puede encontrar una lista de implementaciones de JSR 353:

¿Cuáles son las API que implementan JSR-353 (JSON)?

Y para ayudarte a decidir ... También encontré este artículo:

http://blog.takipi.com/the-ultimate-json-library-json-simple-vs-gson-vs-jackson-vs-json/

Si opta por Jackson, aquí hay un buen artículo sobre la conversión entre JSON a / desde Java usando Jackson: https://www.mkyong.com/java/how-to-convert-java-object-to-from-json- jackson /

¡Espero eso ayude!

Jose Manuel Gomez Alvarez
fuente
Estás señalando la versión 1 de la biblioteca Jackson. Sugiero utilizar la versión actual de la biblioteca Jackson.
Herbert Yu
4

Puedes usar Jayway JsonPath . A continuación se muestra un enlace de GitHub con código fuente, detalles de pom y buena documentación.

https://github.com/jayway/JsonPath

Por favor siga los pasos a continuación.

Paso 1 : Agregue la dependencia de ruta JSON jayway en su ruta de clase usando Maven o descargue el archivo JAR y agréguelo manualmente.

<dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.2.0</version>
</dependency>

Paso 2 : guarde su entrada JSON como un archivo para este ejemplo. En mi caso, guardé su JSON como sampleJson.txt. Tenga en cuenta que se perdió una coma entre pageInfo y las publicaciones.

Paso 3 : Lea el contenido JSON del archivo anterior usando bufferedReader y guárdelo como String.

BufferedReader br = new BufferedReader(new FileReader("D:\\sampleJson.txt"));

        StringBuilder sb = new StringBuilder();
        String line = br.readLine();

        while (line != null) {
            sb.append(line);
            sb.append(System.lineSeparator());
            line = br.readLine();
        }
        br.close();
        String jsonInput = sb.toString();

Paso 4 : Analiza tu cadena JSON usando el analizador JSONway JSON.

Object document = Configuration.defaultConfiguration().jsonProvider().parse(jsonInput);

Paso 5 : Lea los detalles como a continuación.

String pageName = JsonPath.read(document, "$.pageInfo.pageName");
String pagePic = JsonPath.read(document, "$.pageInfo.pagePic");
String post_id = JsonPath.read(document, "$.posts[0].post_id");

System.out.println("$.pageInfo.pageName " + pageName);
System.out.println("$.pageInfo.pagePic " + pagePic);
System.out.println("$.posts[0].post_id " + post_id);

El resultado será :

$.pageInfo.pageName = abc
$.pageInfo.pagePic = http://example.com/content.jpg
$.posts[0].post_id  = 123456789012_123456789012
Ravi Durairaj
fuente
3

Tengo JSON así:

{
   "pageInfo": {
         "pageName": "abc",
         "pagePic": "http://example.com/content.jpg"
    }
}

Clase de Java

class PageInfo {

    private String pageName;
    private String pagePic;

    // Getters and setters
}

Código para convertir este JSON a una clase Java.

    PageInfo pageInfo = JsonPath.parse(jsonString).read("$.pageInfo", PageInfo.class);

Maven

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.2.0</version>
</dependency>
Parth Solanki
fuente
2

Se puede usar la anotación Apache @Model para crear clases de modelos Java que representan la estructura de los archivos JSON y usarlos para acceder a varios elementos en el árbol JSON . A diferencia de otras soluciones, esta funciona completamente sin reflexión y, por lo tanto, es adecuada para entornos donde la reflexión es imposible o conlleva una sobrecarga significativa.

Hay un proyecto de muestra de Maven que muestra el uso. En primer lugar, define la estructura:

@Model(className="RepositoryInfo", properties = {
    @Property(name = "id", type = int.class),
    @Property(name = "name", type = String.class),
    @Property(name = "owner", type = Owner.class),
    @Property(name = "private", type = boolean.class),
})
final class RepositoryCntrl {
    @Model(className = "Owner", properties = {
        @Property(name = "login", type = String.class)
    })
    static final class OwnerCntrl {
    }
}

y luego usa las clases RepositoryInfo y Owner generadas para analizar el flujo de entrada proporcionado y recoger cierta información mientras lo hace:

List<RepositoryInfo> repositories = new ArrayList<>();
try (InputStream is = initializeStream(args)) {
    Models.parse(CONTEXT, RepositoryInfo.class, is, repositories);
}

System.err.println("there is " + repositories.size() + " repositories");
repositories.stream().filter((repo) -> repo != null).forEach((repo) -> {
    System.err.println("repository " + repo.getName() + 
        " is owned by " + repo.getOwner().getLogin()
    );
})

¡Eso es! Además de eso, aquí hay un resumen en vivo que muestra un ejemplo similar junto con la comunicación de red asíncrona.

Jaroslav Tulach
fuente
2

jsoniter(jsoniterator) es una biblioteca json relativamente nueva y simple, diseñada para ser simple y rápida. Todo lo que necesita hacer para deserializar los datos json es

JsonIterator.deserialize(jsonData, int[].class);

donde jsonDataes una cadena de datos json.

Visite el sitio web oficial para más información.

Pika el mago de las ballenas
fuente
1

Podemos usar la clase JSONObject para convertir una cadena JSON en un objeto JSON e iterar sobre el objeto JSON. Usa el siguiente código.

JSONObject jObj = new JSONObject(contents.trim());
Iterator<?> keys = jObj.keys();

while( keys.hasNext() ) {
  String key = (String)keys.next();
  if ( jObj.get(key) instanceof JSONObject ) {           
    System.out.println(jObj.getString(String key));
  }
}
Herrero
fuente
2
Esto es solo para Android
Ľubomír
No es solo Android: docs.oracle.com/javaee/7/api/javax/json/JsonObject.html
Dermot Canniffe
1
@DermotCanniffe es solo Android.
user4020527
1

Puede utilizar la biblioteca de análisis de flujo de DSM para analizar documentos json y XML complejos. DSM analiza los datos solo una vez y no carga todos los datos en la memoria.

Digamos que tenemos clase de página para deserializar datos json dados.

Clase de página

public class Page {
    private String pageName;
    private String pageImage;
    private List<Sting> postIds;

    // getter/setter

}

Crea un archivo de mapeo yaml.

result:
  type: object     # result is array
  path: /posts
  fields:
    pageName:
        path: /pageInfo/pageName
    pageImage:
        path: /pageInfo/pagePic
    postIds:
      path: post_id
      type: array

Use DSM para extraer campos.

DSM dsm=new DSMBuilder(new File("path-to-yaml-config.yaml")).create(Page.class);
Page page= (Page)dsm.toObject(new path-to-json-data.json");

variable de página serializada a json:

{
  "pageName" : "abc",
  "pageImage" : "http://example.com/content.jpg",
  "postIds" : [ "123456789012_123456789012" ]
}

DSM es muy bueno para json y xml complejos.

mfe
fuente
0

Puede usar JsonNodepara una representación de árbol estructurado de su cadena JSON. Es parte de la sólida biblioteca de Jackson Jackson que es omnipresente.

ObjectMapper mapper = new ObjectMapper();
JsonNode yourObj = mapper.readTree("{\"k\":\"v\"}");
slashron
fuente