Como analisar JSON em Java

1049

Eu tenho o seguinte texto JSON. Como posso analisá-lo para obter os 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
fonte
7
As bibliotecas JSON embutidas do java são a maneira mais rápida de fazer isso, mas, na minha experiência, o GSON é a melhor biblioteca para analisar um JSON em um POJO sem dor.
Iman Akbari
16
Esta é a primeira pergunta altamente votada e protegida cujas respostas eu achei as mais confusas
Riyafa Abdul Hameed
6
@JaysonMinard concordou. Pediu a intervenção mod. Isso deve ser fechado realmente. Inicialmente, assumi (erroneamente) que não podia fazê-lo enquanto a pergunta estava protegida, então eu a desprotegi e fiz minha parte. Protegeu-o agora para evitar respostas de baixa repetição e similares, enquanto aguarda um mod.
Mena
4
"Esta questão não mostra nenhum esforço de pesquisa" - Dica do botão Downvote
Jean-François Corbett
6
Esta questão está sendo discutida no Meta .
Mark Amery

Respostas:

754

A biblioteca org.json é fácil de usar. Exemplo de código abaixo:

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");
    ......
}

Você pode encontrar mais exemplos em: Parse JSON in Java

Frasco para download: http://mvnrepository.com/artifact/org.json/json

user1931858
fonte
15
Eu concordo com @StaxMan. Eu apenas tentei org.json e é terrivelmente complicado. Realmente não brinca com os tipos padrão de Java Collection, por exemplo.
Ken Williams
7
@StaxMan Eu escolheria org.jsonoutras bibliotecas para a análise JSON simples, sem sequer olhar. É a biblioteca de referência que Douglas Crockford (o descobridor do JSON) criou.
Omar Al-Ithawi
31
@OmarIthawi isso é bobo. É uma prova de conceito com API desajeitada, implementação ineficiente. Eu acho que é melhor considerar as bibliotecas por seus próprios méritos, em vez de tentar deduzir a qualidade da visibilidade de seus autores - Doug conseguiu muitas coisas, mas isso realmente não muda as qualidades da lib específica. Há 10 anos, era o único jogo na cidade, mas desde então houve muitos progressos positivos. É como Struts de json libs.
StaxMan
12
org.json está entre as piores bibliotecas json. Deve-se examinar o conjunto de recursos e o desempenho das bibliotecas json disponíveis antes de escolher. Aqui está uma referência que eu comparei jackson, gson, org.json, genson usando JMH: github.com/fabienrenaud/java-json-benchmark . Jackson é o vencedor claro aqui.
fabien
4
A Licença não inclui nenhum licenciamento Open Source comumente usado e também possui direitos autorais.
Christian Vielma
537

Por uma questão de exemplo, vamos supor que você tenha uma classe Personcom apenas a name.

private class Person {
    public String name;

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

Google GSON ( Maven )

Meu favorito pessoal quanto à grande serialização / desserialização de objetos JSON.

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"}

Atualizar

Se você deseja obter um único atributo, também pode fazê-lo facilmente com a biblioteca do Google:

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

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

Org.JSON ( Maven )

Se você não precisa de desserialização de objetos, mas simplesmente obtém um atributo, tente o org.json ( ou veja o exemplo do GSON acima! )

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
fonte
16
Boa resposta. Uma sugestão para melhorias menores: o GSON e o Jackson também suportam o uso da representação em árvore JSON (para Jackson, estes são JsonNodes, o GSON tem algo semelhante). Pode ser bom mostrar trechos, pois é semelhante à única maneira que o org.json oferece.
StaxMan
Duas outras bibliotecas vale a pena mencionar (no interesse da integralidade): json-simples e da Oracle JSONP
Jake Stayman
3
@NeonWarge, por quê? Parece-me que esta resposta pressupõe que uma pessoa já tenha definido uma classe Java que contém exatamente os mesmos campos que a string JSON, nada menos e nada mais. Esta é uma suposição bastante forte.
Andrea Lazzarotto
1
json-simple e jsonp do oracle têm um desempenho terrível: github.com/fabienrenaud/java-json-benchmark Para obter o desempenho, escolha jackson ou dsljson.
Fabian1 de
O GSON não suporta filtragem dinâmica de campos em outros níveis além da raiz!
Gangnus 6/08/16
102
  1. Se alguém quiser criar um objeto Java a partir do JSON e vice-versa, use os frascos de terceiros GSON ou 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. Mas se alguém quiser apenas analisar uma string JSON e obter alguns valores (ou criar uma string JSON do zero para enviar por fio), use o jar JaveEE que contém JsonReader, JsonArray, JsonObject etc. Você pode fazer o download da implementação dessa especificações como javax.json. Com esses dois jarros, sou capaz de analisar o json e usar os valores.

    Na verdade, essas APIs seguem o modelo de análise 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");
indefinido
fonte
4
@ indefinido Se eu tivesse que adivinhar, diria que a votação foi reduzida porque não responde à pergunta do pôster original: "Qual é o código necessário?" As respostas que foram votadas forneceram trechos de código.
Jewbix.cube
4
Nota: Jackson e GSON suportam ligação no estilo de árvore e / ou Maps / Lists, portanto, não há necessidade de usar o pacote Java EE (javax.json). javax.json tem pouco a oferecer além de Jackson ou GSON.
StaxMan
Sugiro adicionar um link para a biblioteca JavaEE.
Basil Bourque
72

analisador quick-json é muito direto, flexível, muito rápido e personalizável. Tente

Recursos:

  • Compatível com a especificação JSON (RFC4627)
  • Analisador JSON de alto desempenho
  • Suporta abordagem de análise flexível / configurável
  • Validação configurável de pares de chave / valor de qualquer hierarquia JSON
  • Fácil de usar # Pegada muito pequena
  • Gera exceções amigáveis ​​ao desenvolvedor e fáceis de rastrear
  • Suporte para validação personalizada conectável - Chaves / valores podem ser validados configurando validadores personalizados como e quando encontrados
  • Suporte ao analisador de validação e não validação
  • Suporte para dois tipos de configuração (JSON / XML) para usar o analisador de validação de JSON rápido
  • Requer JDK 1.5
  • Nenhuma dependência de bibliotecas externas
  • Suporte à geração JSON através da serialização de objetos
  • Suporte para seleção de tipo de coleção durante o processo de análise

Pode ser usado assim:

JsonParserFactory factory=JsonParserFactory.getInstance();
JSONParser parser=factory.newJsonParser();
Map jsonMap=parser.parseJson(jsonString);
rputta
fonte
3
Existe um javadoc disponível?
jboi
24
Este pacote não pode manipular valores vazios ao analisar. Por exemplo: ... "description": "" ... lança uma exceção
Ivan
6
Corrigi esse problema (e muitos outros) em code.google.com/p/quick-json/issues/detail?id=11 Espero que o autor dedique algum tempo para corrigi-lo no release oficial.
noamik
8
Dos recursos listados, nada é exclusivo em comparação com outras opções - e a reivindicação de alto desempenho não é suportada por nada; ao contrário das bibliotecas mais antigas (Gson, Jackson, Genson, Boon), incluídas em benchmarks como github.com/eishay/jvm-serializers , github.com/novoj/JavaJsonPerformanceTest ou developer.com/lang/jscript/… - I não viu essa biblioteca incluída em testes ou menciona que ela é amplamente usada.
StaxMan
26
Este projeto parece estar morto e parece não estar mais hospedado no repositório central do Maven.
#
40

Você poderia usar o Google Gson .

Usando esta biblioteca, você só precisa criar um modelo com a mesma estrutura JSON. Em seguida, o modelo é preenchido automaticamente. Você precisa chamar suas variáveis ​​como chaves JSON ou usar@SerializedName se desejar usar nomes diferentes.

JSON

Do seu exemplo:

{
    "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;
}

Análise

Agora você pode analisar usando a biblioteca Gson:

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

Importação Gradle

Lembre-se de importar a biblioteca no arquivo Gradle do aplicativo

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

Geração automática de modelo

Você pode gerar o modelo a partir do JSON automaticamente usando ferramentas online como esta .

lubilis
fonte
38

Quase todas as respostas fornecidas requerem uma desserialização completa do JSON em um objeto Java antes de acessar o valor na propriedade de interesse. Outra alternativa, que não segue essa rota, é usar o JsonPATH, que é como o XPath for JSON e permite o deslocamento de objetos JSON.

É uma especificação e o pessoal da JayWay criou uma implementação Java para a especificação, que você pode encontrar aqui: https://github.com/jayway/JsonPath

Então, basicamente, para usá-lo, adicione-o ao seu projeto, por exemplo:

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

e 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 ...

Verifique a página de especificação do JsonPath para obter mais informações sobre as outras maneiras de atravessar o JSON.

dade
fonte
Essa é uma biblioteca muito boa, especialmente para ler e atualizar o JSON, mas cuidado com alguns problemas conhecidos dessa biblioteca. Veja [1]: github.com/json-path/JsonPath/issues/272 [2]: github.com/json-path/JsonPath/issues/375
papigee
38

A - Explicação

É possível usar as bibliotecas Jackson , para vincular a Cadeia JSON às instâncias POJO ( Plain Old Java Object ). POJO é simplesmente uma classe com apenas campos privados e métodos públicos de obtenção / instalação. Jackson vai percorrer os métodos (usando reflexão ) e mapeia o objeto JSON para a instância do POJO, à medida que os nomes de campo da classe se ajustam aos nomes de campo do objeto JSON.

No seu objeto JSON, que na verdade é um objeto composto , o objeto principal consiste em dois subobjetos. Portanto, nossas classes POJO devem ter a mesma hierarquia. Vou chamar o objeto JSON inteiro como página objeto de . O objeto de página consiste em um objeto PageInfo e uma matriz de objetos Post .

Portanto, temos que criar três classes POJO diferentes;

  • Page Class, um composto de classe PageInfo e matriz de instâncias pós
  • Classe PageInfo
  • Classe Posts

O único pacote que usei é o Jackson ObjectMapper, o que fazemos é vincular dados;

com.fasterxml.jackson.databind.ObjectMapper

As dependências necessárias, os arquivos jar estão listados abaixo;

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

Aqui está o código necessário;

B - Classe principal do 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 - Classe POJO filho: 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 - Classe POJO Criança: Post

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 - Arquivo JSON de amostra: sampleJSONFile.json

Acabei de copiar seu exemplo JSON para esse arquivo e colocá-lo na pasta do projeto.

{
   "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 Demo

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 - Saída de demonstração

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
fonte
26

Use minimal-json que é muito rápido e fácil de usar. Você pode analisar a partir de String obj e Stream.

Dados de amostra:

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

Análise:

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

Criando 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
fonte
Como será o pojo?
Jesse
Para o Pojo, use gson. Esta biblioteca não suporta.
Sakib Sami 29/03
22

Acredito que a melhor prática seja passar pela API Java JSON oficial, que ainda está em andamento.

Giovanni Botta
fonte
7
Desde que respondi, comecei a usar Jackson e acho que é uma das melhores bibliotecas disponíveis para desserialização de JSON.
Giovanni Botta
2
Por que eles re-uso JSONP para diferentes algo média de JSON com padding ...?
Chris Wesseling
@ChrisWesseling O que você quer dizer?
Giovanni Botta 14/05
"API Java para processamento JSON (JSON-P)" é o título do documento ao qual você vincula. E isso me confundiu, porque eu sabia que JSONP significava outra coisa.
Chris Wesseling
1
@ChrisWesseling oh isso é confuso. Foi isso que eles escolheram para a especificação. No entanto, como eu disse, eu iria direto para Jackson.
Giovanni Botta 14/05
22

Como ninguém o mencionou ainda, aqui está o começo de uma solução usando Nashorn (parte do tempo de execução JavaScript do Java 8, mas descontinuada no Java 11).

Solução

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));
}

Comparação de desempenho

Eu escrevi conteúdo JSON contendo três matrizes, respectivamente, 20, 20 e 100 elementos. Eu só quero obter os 100 elementos da terceira matriz. Eu uso a seguinte função JavaScript para analisar e obter minhas entradas.

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

A execução da chamada um milhão de vezes usando Nashorn leva de 7,5 a 7,8 segundos

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

org.json leva 20 ~ 21 segundos

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

Jackson leva 6,5 ​​~ 7 segundos

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

Nesse caso, Jackson tem um desempenho melhor que Nashorn, que tem um desempenho muito melhor que o org.json. A API Nashorn é mais difícil de usar que a do org.json ou do Jackson. Dependendo dos seus requisitos, Jackson e Nashorn podem ser soluções viáveis.

otonglet
fonte
1
Qual é a unidade " ""? Não polegadas? São segundos? Minutos?
Peter Mortensen
1
@PeterMortensen significa segundos. Como não está claro, vou mudar. Obrigado pela revisão.
Otonglet
2
Infelizmente, Nashorn está obsoleto no Java 11. JEP 335 .
Por Mildner
1
Sei que Nashorn está obsoleto, mas gostei desta resposta porque não queria nenhuma dependência; no entanto, tive que refazer um pouco o exemplo: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 22/03
21

O exemplo abaixo mostra como ler o texto na pergunta, representado como a variável "jsonText". Esta solução usa a API Java EE7 javax.json (mencionada em algumas das outras respostas). A razão pela qual a adicionei como resposta separada é que o código a seguir mostra como realmente acessar alguns dos valores mostrados na pergunta. Uma implementação da API javax.json seria necessária para executar esse código. O pacote completo para cada uma das classes exigidas foi incluído, pois eu não queria declarar instruções "import".

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");

Agora, antes que alguém rejeite essa resposta porque ela não usa GSON, org.json, Jackson ou qualquer outra estrutura de terceiros disponível, é um exemplo de "código necessário" por pergunta para analisar o texto fornecido. Estou ciente de que a adesão ao padrão atual JSR 353 não estava sendo considerada para o JDK 9 e, como tal, as especificações do JSR 353 devem ser tratadas da mesma forma que qualquer outra implementação de manipulação de JSON de terceiros.

justin.hughey
fonte
15

Isso me impressionou com o quão fácil foi. Você pode simplesmente passar Stringseu JSON em espera para o construtor de um JSONObject no pacote org.json padrão.

JSONArray rootOfPage =  new JSONArray(JSONString);

Feito. Larga o microfone . Isso funciona JSONObjectstambém. Depois disso, você pode simplesmente examinar sua hierarquia Objectsusando os get()métodos em seus objetos.

brainmurphy1
fonte
13
O JSONArraytipo não faz parte da API J2SE JDK e você não diz qual API ou biblioteca de terceiros fornece esse tipo.
Bobulous
2
Não que eu recomendaria usá-lo, mas acho que isso se refere ao pacote "org.json" em json.org/java . É usado para ser usado antes de boas bibliotecas Java tornou-se disponível, mas isso foi anos atrás (2008 ou antes)
StaxMan
1
Ou brainmurphy1 significa JSONArray no Android?
21418 Alexander Farber
12

Existem muitas bibliotecas JSON disponíveis em Java.

Os mais notórios são: Jackson, GSON, Genson, FastJson e org.json.

Normalmente, há três coisas que devemos considerar para escolher qualquer biblioteca:

  1. atuação
  2. Facilidade de uso (o código é simples de escrever e legível) - que acompanha os recursos.
  3. Para aplicativos móveis: tamanho da dependência / jar

Especificamente para bibliotecas JSON (e quaisquer bibliotecas de serialização / desserialização), a ligação de dados também é geralmente interessante, pois elimina a necessidade de escrever o código da caldeira para compactar / descompactar os dados.

Para 1, consulte esta referência: https://github.com/fabienrenaud/java-json-benchmark que fiz usando JMH que compara (jackson, gson, genson, fastjson, org.json, jsonp) o desempenho de serializadores e desserializadores usando stream e APIs de ligação de dados. Para o 2, você pode encontrar vários exemplos na Internet. A referência acima também pode ser usada como fonte de exemplos ...

Análise rápida do benchmark: Jackson executa de 5 a 6 vezes melhor que o org.json e mais do que duas vezes melhor que o GSON.

Para seu exemplo específico, o código a seguir decodifica seu json com 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.
    }
}

Deixe-me saber se você tiver alguma dúvida.

fabien
fonte
11

Além de outras respostas, recomendo este serviço on-line de código- fonte jsonschema2pojo.org para gerar rapidamente classes Java a partir do esquema json ou json para GSON, Jackson 1.x ou Jackson 2.x. Por exemplo, se você tiver:

{
   "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
         }
    ]
}

O jsonschema2pojo.org para o GSON gerou:

@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
fonte
9

Se você tiver alguma classe Java (diga Mensagem) representando a sequência JSON (jsonString), poderá usar a biblioteca Jackson JSON com:

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

e do objeto de mensagem, você pode buscar qualquer um de seus atributos.

Shailendra Singh
fonte
9

O Gson é fácil de aprender e implementar. O que precisamos saber é seguir dois métodos

  • toJson () - converte objeto Java para o formato JSON

  • fromJson () - converte JSON em 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
fonte
Para um conhecimento completo sobre o Gson, consulte os links abaixo. github.com/google/gson/blob/master/UserGuide.md
venkat 5/02/16
9

Existem muitas bibliotecas de código aberto presentes para analisar o conteúdo JSON em um objeto ou apenas para ler valores JSON. Seu requisito é apenas ler valores e analisá-los em objetos personalizados. Portanto, a biblioteca org.json é suficiente no seu caso.

Use a biblioteca org.json para analisá-la e criar JsonObject:

JSONObject jsonObj = new JSONObject(<jsonStr>);

Agora, use este objeto para obter seus valores:

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

Você pode ver um exemplo completo aqui:

Como analisar JSON em Java

lalitbhagtani
fonte
Parece que todas as suas respostas contêm um link para esse site. Se for spam, pare. Se não estiver, desculpe a confusão, mas não acho necessário postar um link em todas as suas respostas.
Donald Duck
1
É difícil dar uma resposta, onde você pode explicar todos os cenários. Como neste caso, como ler json array ou vários objetos json. Mesmo se eu fizer isso, a resposta seria muito longa e a pessoa pode ficar confusa. Então, eu dou um link onde a explicação adequada é dada, com exemplo apropriado. Ele pode optar por visitar ou pode usar apenas minha explicação.
Lalitbhagtani 3/03
1
Parece-me que o link que você forneceu apenas demonstra como ler JSON. Onde posso encontrar informações sobre como JSON também?
Lampros Tzanetos
Desculpe, mas não entendi sua pergunta: - "sobre como JSON também"
lalitbhagtani
7

Faça algo como isto:

JSONParser jsonParser = new JSONParser();
JSONObject obj = (JSONObject) jsonParser.parse(contentString);
String product = (String) jsonObject.get("productId");
Sreekanth
fonte
10
Er, que biblioteca é essa?
Stewart
2
Eu acho que ele está usando org.json.simple
Lasitha Yapa
7

Você pode usar a Biblioteca Gson para analisar a sequência 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();

Você também pode percorrer a matriz "posts" da seguinte maneira:

JsonArray posts = jsonObject.getAsJsonArray("posts");
for (JsonElement post : posts) {
  String postId = post.getAsJsonObject().get("post_id").getAsString();
  //do something
}
LittleBigUllah
fonte
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
fonte
9
Por favor, explique sua resposta, pois as respostas somente de código ajudam outras pessoas a menos do que o código bem documentado. Veja "dê a um homem um peixe e você o alimenta por um dia; ensine um homem a pescar e você o alimenta por toda a vida" .
Wai Ha Lee
Seria bom mencionar que isso é para a lib 'org.json'. No entanto, não acho que essa seja uma boa maneira de fazê-lo sendo muito detalhada, e a lib 'org.json' sendo obsoleta (API lenta e complicada). Existem melhores opções: GSON, Jackson, Boon, Genson para usar.
StaxMan
5

Leia a seguinte postagem no blog, JSON in Java .

Este post é um pouco antigo, mas ainda quero responder a sua pergunta.

Etapa 1: Crie uma classe POJO dos seus dados.

Etapa 2: agora crie um 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 referência adicional, você pode consultar o seguinte link .

sumit kumar
fonte
4

As principais respostas desta página usam exemplos muito simples, como objetos com uma propriedade (por exemplo, {name: value}). Eu acho que esse exemplo ainda simples, mas da vida real, pode ajudar alguém.

Portanto, este é o JSON retornado pela API do Google Tradutor:

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

Quero recuperar o valor do atributo "translateText", por exemplo, "Arbeit" usando o Gson do Google.

Duas abordagens possíveis:

  1. Recupere apenas um atributo necessário

    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. Criar objeto Java a partir de 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
fonte
4

Primeiro você precisa selecionar uma biblioteca de implementação para fazer isso.

A API Java para processamento JSON (JSR 353) fornece APIs portáteis para analisar, gerar, transformar e consultar JSON usando modelo de objeto e APIs de streaming.

A implementação de referência está aqui: https://jsonp.java.net/

Aqui você pode encontrar uma lista de implementações do JSR 353:

O que é a API que implementa JSR-353 (JSON)

E para ajudá-lo a decidir ... Encontrei este artigo também:

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

Se você for para Jackson, aqui está um bom artigo sobre a conversão entre JSON para / de Java usando Jackson: https://www.mkyong.com/java/how-to-convert-java-object-to-from-json- jackson /

Espero que ajude!

Jose Manuel Gomez Alvarez
fonte
Você está apontando para a versão 1 da biblioteca Jackson. É altamente recomendável usar a versão atual da biblioteca Jackson.
Herbert Yu
4

Você pode usar o Jayway JsonPath . Abaixo está um link do GitHub com código fonte, detalhes do pom e boa documentação.

https://github.com/jayway/JsonPath

Por favor, siga os passos abaixo.

Etapa 1 : adicione a dependência do caminho JSON jayway no caminho da sua classe usando o Maven ou faça o download do arquivo JAR e adicione-o manualmente.

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

Etapa 2 : salve sua entrada JSON como um arquivo para este exemplo. No meu caso, salvei seu JSON como sampleJson.txt. Observe que você perdeu uma vírgula entre pageInfo e postagens.

Etapa 3 : leia o conteúdo JSON do arquivo acima usando bufferedReader e salve-o 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();

Etapa 4 : Analise sua string JSON usando o analisador jayway JSON.

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

Etapa 5 : Leia os detalhes como abaixo.

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);

A saída será :

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

Eu tenho JSON assim:

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

Classe Java

class PageInfo {

    private String pageName;
    private String pagePic;

    // Getters and setters
}

Código para converter esse JSON em uma classe 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
fonte
2

Pode-se usar a anotação Apache @Model para criar classes de modelo Java que representam a estrutura dos arquivos JSON e usá-las para acessar vários elementos na árvore JSON . Ao contrário de outras soluções, esta funciona completamente sem reflexão e, portanto, é adequada para ambientes em que a reflexão é impossível ou ocorre com sobrecarga significativa.

Há um exemplo de projeto do Maven mostrando o uso. Antes de tudo, define a estrutura:

@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 {
    }
}

e, em seguida, usa as classes RepositoryInfo e Owner geradas para analisar o fluxo de entrada fornecido e coletar determinadas informações ao fazer isso:

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()
    );
})

É isso! Além disso, aqui está uma essência ao vivo que mostra um exemplo semelhante, juntamente com a comunicação de rede assíncrona.

Jaroslav Tulach
fonte
2

jsoniter(jsoniterator) é uma biblioteca json relativamente nova e simples, projetada para ser simples e rápida. Tudo o que você precisa fazer para desserializar dados json é

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

onde jsonDataé uma sequência de dados json.

Confira o site oficial para mais informações.

Pika, o Mago das Baleias
fonte
1

Podemos usar a classe JSONObject para converter uma string JSON em um objeto JSON e iterar sobre o objeto JSON. Use o seguinte 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));
  }
}
ferreiro
fonte
2
Este é apenas o Android #
05517
Não é apenas o android: docs.oracle.com/javaee/7/api/javax/json/JsonObject.html
Dermot Canniffe
1
@DermotCanniffe é apenas Android.
user4020527
1

Você pode usar a biblioteca de análise de fluxo do DSM para analisar documentos json e XML complexos. O DSM analisa dados apenas uma vez e não carrega todos os dados na memória.

Digamos que temos Página classe para desserializar dados json.

Classe da página

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

    // getter/setter

}

Crie um arquivo de mapeamento 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 o DSM para extrair 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");

variável de página serializada para json:

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

O DSM é muito bom para json e xml complexos.

mfe
fonte
0

Você pode usar JsonNodepara uma representação em árvore estruturada da sua cadeia JSON. Faz parte da biblioteca sólida de Jackson , que é onipresente.

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