Como converter Json com Java

Olá pessoal.

Hoje vou escrever sobre como converter objetos Java em objetos Json e vice-versa. O objetivo é apresentar alguns códigos que demonstram este processo.

O Json já é uma realidade inclusive no mercado. É muito mais fácil trabalhar com Json com javascript e com o Java também.

A quantidade de dados trafegados também cai muito, uma vez que o Json não utiliza o conceito de tags.

Para saber mais sobre Json, visite este link.

Criar um Json a partir do Java?

Para fazer as conversões de Json para Java (Json2Java ou J2J) vou utilizar uma biblioteca do google chamada gson.

Para começar, vamos criar uma classe que sera convertida em um Json. Essa classe sera um pojo bastante simples:

public class Pessoa {

	private String nome;
	private int idade;

	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public int getIdade() {
		return idade;
	}
	public void setIdade(int idade) {
		this.idade = idade;
	}

}

Nada diferente nesta classe, ela apenas representa uma pessoa e possui 2 atributos. Vamos apresentar agora uma classe que vai criar um objeto Pessoa, e convertê-lo em um json. Veja como é simples:

import com.google.gson.Gson;

public class ConverterJson {

	public static void main(String[] args) {
		Pessoa p = new Pessoa();
		p.setIdade(15);
		p.setNome("Almiro Fagundes");
		Gson g = new Gson();
		String json = g.toJson(p);
		System.out.println(json);
	}

}

O método toJson da classe Gson faz a conversão do objeto Pessoa, sem a necessidade de mapeamentos ou etapas adicionais.
A saída gerada é:

{"nome":"Almiro Fagundes","idade":15}

Como alterar nome do atributo e trabalhar com Datas?

Simples não? Vamos complicar um pouco, adicionando um campo data e personalizando o nome do atributo gerado no json:

import java.util.Date;
import com.google.gson.annotations.SerializedName;

	public class Pessoa {

	@SerializedName(value = "nome_completo")
	private String nome;
	private int idade;
	@SerializedName(value = "data_nascimento")
	private Date dataNascimento;

	public String getNome() {
		return nome;
	}
	public Date getDataNascimento() {
		return dataNascimento;
	}
	public void setDataNascimento(Date dataNascimento) {
		this.dataNascimento = dataNascimento;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public int getIdade() {
		return idade;
	}
	public void setIdade(int idade) {
		this.idade = idade;
	}

}

Observe que adicionamos uma notação chamada SerializedName que indica qual sera o nome do atributo no Json. Vamos converter o nosso objeto Pessoa para vermos o resultado.

	public static void main(String[] args) {
		Pessoa p = new Pessoa();
		p.setIdade(15);
		p.setNome("Almiro Fagundes");
		p.setDataNascimento(new Date());
		Gson g = new Gson();
		String json = g.toJson(p);
		System.out.println(json);
	}

A saída gerada no exemplo acima é:

{"nome_completo":"Almiro Fagundes","idade":15,"data_nascimento":"Aug 4, 2012 1:19:59 AM"}

Ok, conseguimos alterar o nome do atributo, mas o formato que a data foi impressa não ficou legal. Vamos definir então um pattern para a nossa data. E essa tarefa é muito simples também:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class ConverterJson {

	public static void main(String[] args) {
		Pessoa p = new Pessoa();
		p.setIdade(15);
		p.setNome("Almiro Fagundes");
		p.setDataNascimento(new Date());
		GsonBuilder builder = new GsonBuilder();
		builder.setDateFormat("dd/MM/yyyy");
		Gson g = builder.create();
		String json = g.toJson(p);
		System.out.println(json);
	}	
}

Opa, agora temos uma pequena diferença. Ao invés de criarmos um objeto Gson diretamente estamos utilizando um Builder. Neste objeto definimos qual o Pattern utilizado para a data. Agora sim, a saída gerada:

{"nome_completo":"Almiro Fagundes","idade":15,"data_nascimento":"04/08/2012"}

E se eu tiver que trabalhar com List?

Bom, e se o objeto que tem que ser convertido for um objeto do tipo List? Vamos fazer um teste, e adicionar uma lista de String com os nomes dos irmãos na classe Pessoa.

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.google.gson.annotations.SerializedName;

public class Pessoa {

	@SerializedName(value = "nome_completo")
	private String nome;
	private int idade;
	@SerializedName(value = "data_nascimento")
	private Date dataNascimento;

	private List<String> irmaos = new ArrayList<>();

	public List<String> getIrmaos() {
		return irmaos;
	}
	public void setIrmaos(List<String> irmaos) {
		this.irmaos = irmaos;
	}
	public String getNome() {
		return nome;
	}
	public Date getDataNascimento() {
		return dataNascimento;
	}
	public void setDataNascimento(Date dataNascimento) {
		this.dataNascimento = dataNascimento;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public int getIdade() {
		return idade;
	}
	public void setIdade(int idade) {
		this.idade = idade;
	}

}

Observe que adicionamos uma lista como atributo da classe. Vamos agora adicionar alguns dados a ela e ver o resultado convertido.

import java.util.Date;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class ConverterJson {

	public static void main(String[] args) {
		Pessoa p = new Pessoa();
		p.setIdade(15);
		p.setNome("Almiro Fagundes");
		p.setDataNascimento(new Date());
		p.getIrmaos().add("Marilde Louzato");
		p.getIrmaos().add("João Fagundes");
		GsonBuilder builder = new GsonBuilder();
		builder.setDateFormat("dd/MM/yyyy");
		Gson g = builder.create();
		String json = g.toJson(p);
		System.out.println(json);
	}

}

E o resultado é:

{"nome_completo":"Almiro Fagundes","idade":15,"data_nascimento":"04/08/2012","irmaos":["Marilde Louzato","João Fagundes"]}

Podemos perceber que para todos estes casos a biblioteca fez a conversão de uma forma elegante, sem ser intrusiva ao código. Tivemos que adicionar anotações apenas quando decidimos formatar os campos do objeto Json.

Outros testes que fiz foi com Listas de outros objetos e inner class. A biblioteca conseguiu fazer a conversão em todos estes casos.

E quando eu quero criar um objeto Java?

O processo inverso, adivinhem? Sim, é bem simples. Vou pegar o último Json gerado e vou fazer o inverso, pedir para ele criar um objeto Java:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class ConverterJson {

	public static void main(String[] args) {
		String json = "{\"nome_completo\":\"Almiro Fagundes\",\"idade\":15,\"data_nascimento\":\"04/08/2012\",\"irmaos\":[\"Marilde Louzato\",\"João Fagundes\"]}";
		GsonBuilder builder = new GsonBuilder();
		builder.setDateFormat("dd/MM/yyyy");
		Gson g = builder.create();
		Pessoa p = g.fromJson(json, Pessoa.class);
		System.out.println("Nome: " + p.getNome());
		System.out.println("Idade: " + p.getIdade());
		System.out.println("Data Nascimento: " + p.getDataNascimento());
		System.out.println("Irmãos: " + p.getIrmaos().toString());
	}

}

E o resultado:

Nome: Almiro Fagundes
Idade: 15
Data Nascimento: Sat Aug 04 00:00:00 BRT 2012
Irmãos: [Marilde Louzato, João Fagundes]

E a conversão foi feita.

Pessoal, muito simples trabalhar com Json em Java. Vocês encontram mais informações no site. Um abraço.