domingo, 21 de fevereiro de 2016

Convertendo objetos Java para JSON usando JSON-P

Falamos aqui na outra postagem sobre JAXB, a biblioteca padrão do Java para conversão de objetos para XML e vice versa. Hoje vamos falar sobre a conversão para JSON(um formato de dados famoso) usando JSON Processing.

JSON Explanation
Para um exemplo sobre uso de JSON com Android, veja esse artigo

API padrão do Java para JSON


O Java, por muitos anos, não tinha um padrão para a conversão de JSON, isso mudou com a JSR 353, que nos trouxe o JSON-P (JSON Processing).
Nessa especificação temos uma nova API para realizar transformação de JSON que é baseada em manipular a estrutura do JSON usando Java. Ou seja, não é uma API de binding, como mostrados para XML(onde podemos fazer a correspondência de um objeto Java para JSON ! Para isso temos a JSON-B(JSON binding), que ainda está em discussão e fará parte do Java EE 8, por enquanto podemos usar a API Jackson.

A API JSON Processing

Para utilizarmos JSON-P, temos que conhecer algumas classes importantes. Veja a tabela traduzida dessa página:

Principais classes e interfaces do pacote javax.json
Classe ou InterfaceDescrição
Json
Contém métodos especifícicos para criar instâncias de parsers JSON, builders e fábricas para criar objetos.
JsonReader
Lê JSON de um Stream e cria objetos de modelo em memória. (objetos de modelo que representam o JSON)
JsonObjectBuilder
JsonArrayBuilder
Cria um modelo de objeto ou um modelo de array na memória adicionando elementos da aplicação.
JsonWriter
Escreve um objeto da memória para um Stream.
JsonValue
Representa um elemento (como um objeto, um array ou um valor) em dados no formato JSON.
JsonStructure
Representa um objeto ou um array no formato JSON. É um subtipo do JsonValue.
JsonObject
JsonArray
Representa um objeto ou um array no tipo JSON.Essas interfaces são subtipos de JsonStructure.
JsonString
JsonNumber
Representam tipos de dados em JSON. Essas interfaces são subtipos de  JsonValue.
JsonException
Indicate que houve um error no processamento do JSON.

Principais classes e interfaces do pacto javax.json.stream
Classe ou interfaceDescrição
JsonParser
Representa um parser baseado em JSON que pode ler dados JSON de um Stream ou de um objeto de modelo.
JsonGenerator
Escreve JSON para um Stream, um elemento por vez.




Se você leu ali em cima,vamos ao código para "digerir" a informação.

Uma aplicação de exemplo


Vamos utilizar o mesmo objeto do post passado, o Artigo. Como iremos usar maven, precisamos adicionar a API e a implementação. Abaixo você pode ver o código Java e o JSON usado. O método javaParaJson gera o JSON a partir de uma lista de artigos e o mesmo JSON gerado será lido no métódo jsonParaJava devidamente comentados.

package org.aprendendojava.jsonp;
import java.util.Date;
public class Artigo {
private String nome;
private Date dataPublicacao;
private String autor;
String conteudo;
public Artigo(String nome, Date dataPublicacao, String autor, String conteudo) {
super();
this.nome = nome;
this.dataPublicacao = dataPublicacao;
this.autor = autor;
this.conteudo = conteudo;
}
// gets e sets...
}
view raw Artigo.java hosted with ❤ by GitHub
[
{
"nome":"Java 8",
"dataPublicacao":"Sun Feb 21 06:25:00 BRT 2016",
"autor":"jesuino",
"conteudo":"java 8 é a melhor release do Java... Tem Lambdas"
},
{
"nome":"Java EE 8",
"dataPublicacao":"Sun Feb 21 06:25:00 BRT 2016",
"autor":"william",
"conteudo":"Em breve..."
},
{
"nome":"Code",
"dataPublicacao":"Sun Feb 21 06:25:00 BRT 2016",
"autor":"Linus Torwalds",
"conteudo":"Talking is cheap, show the code"
}
]
view raw artigos.js hosted with ❤ by GitHub
package org.aprendendojava.jsonp;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.JsonValue;
import javax.json.stream.JsonGenerator;
public class OlaJSONP {
static SimpleDateFormat FORMATOR = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
static String ARQUIVO = OlaJSONP.class.getResource("/artigos.js").getFile();
public static void main(String[] args) throws Exception {
javaParaJson();
jsonParaJava();
}
public static void javaParaJson() throws IOException {
// cria objetos do tipo artigo de exemplo
Artigo a1 = new Artigo("Java 8", new Date(), "jesuino", "java 8 é a melhor release do Java... Tem Lambdas");
Artigo a2 = new Artigo("Java EE 8", new Date(), "william", "Em breve...");
Artigo a3 = new Artigo("Code", new Date(), "Linus Torwalds", "Talking is cheap, show the code");
List<Artigo> artigos = Arrays.asList(a1, a2, a3);
// abrimos o arquivo
FileOutputStream fos = new FileOutputStream(ARQUIVO);
// um gerador de JSON que escreve no arquivo
JsonGenerator geradorJson = Json.createGenerator(fos);
// começamos a escrever um Array JSON
geradorJson.writeStartArray();
for (Artigo artigo : artigos) {
// vamos ler a data em um formato mais legível
String data = FORMATOR.format(artigo.getDataPublicacao());
// começando a escrever o objeto JSON e então as propriedades, por fim fecha o objeto
geradorJson.writeStartObject()
.write("nome", artigo.getNome())
.write("dataPublicacao", data)
.write("autor", artigo.getAutor())
.write("conteudo", artigo.getConteudo())
.writeEnd();
}
// terminamos o array e escremos no Stream (agora devemos ver a saída no console)
geradorJson.writeEnd().close();
System.out.println("Lista de artigos convertidos para JSON: ");
System.out.println(Files.readAllLines(Paths.get(ARQUIVO)));
System.out.println("\n");
}
public static void jsonParaJava() throws Exception {
// Nossa lista de artigos
List<Artigo> artigos = new ArrayList<>();
// aqui estamos lendo o arquivo
InputStream isEntrada = Files.newInputStream( Paths.get(ARQUIVO));
// criamos um leitor Json para o input Stream do arquivo
JsonReader leitor = Json.createReader(isEntrada);
// sabemos que tem um array no topo dele, assim lemos o array
JsonArray arrayArtigos = leitor.readArray();
// para cada valor do Array
for (JsonValue valorJson : arrayArtigos) {
// sabemos que temos um objeto nesse array, assim não precisamos verificar o tipo e já fazer casting
JsonObject objetoJson = (JsonObject) valorJson;
String nome = objetoJson.getString("nome");
String dataPublicacaoStr = objetoJson.getString("dataPublicacao");
String autor = objetoJson.getString("autor");
String conteudo = objetoJson.getString("conteudo");
Date dataPublicacao = FORMATOR.parse(dataPublicacaoStr);
// agora estamos prontos para criar nosso artigo
artigos.add(new Artigo(nome, dataPublicacao, autor, conteudo));
}
// fechando o leitor...
leitor.close();
// pronto! Vamos só imprimiro nossos objetos lidos do arquivo
System.out.println("Artigos lidos: ");
for (Artigo artigo : artigos) {
System.out.println("\tNome: " + artigo.getNome());
System.out.println("\tData Publicação: " + artigo.getDataPublicacao());
System.out.println("\tAutor: " + artigo.getAutor());
System.out.println("\tConteúdo: " + artigo.getConteudo());
System.out.println("\t\t--");
}
}
}
view raw OlaJSONP.java hosted with ❤ by GitHub

Conclusão


Apresentamos JSON-P e falamos da conversão JSON para Java e vice versa. Embora Java ainda não tenha uma forma nativa de lidar com JSON, a API JSON-P é simples de ser usada e a nova API JSON-B promete a mesma facilidade do JAXB para JSON.

O projeto maven usado nessa postagem está on github!



Nenhum comentário:

Postar um comentário