Convertendo JSON para Object
Neste tutorial será demonstrado como converter dados de um arquivo JSON em objetos Java, assim como, converter um objeto Java em arquivo JSON. Os dados do arquivo JSON serão convertidos em uma lista onde cada posição da lista será um objeto do tipo User. Para realizar esta conversão, será usada uma biblioteca de manipulação JSON chamada Jackson.
Para este projeto vou utilizar a seguinte dependência Maven para o Jackson:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.1-1</version>
</dependency>
1. Classe Phone
Criei um pequeno exemplo onde terei duas classes envolvidas, que representariam classes de entidades se estivéssemos trabalhando com banco de dados. A primeira classe a ser analisada é a Phone
, conforme a Listagem 1.
Listagem 1. Classe Phone
package com.mballem.json.domain;
import java.io.Serializable;
/**
* Created by http://www.mballem.com/ on 09/02/2016.
*/
public class Phone implements Serializable {
private Integer id;
private PhoneType type;
private String number;
public Phone() {
super();
}
public Phone(Integer id, PhoneType type, String number) {
this.id = id;
this.type = type;
this.number = number;
}
//getters/setter omitidos
public enum PhoneType {
MOBILE, OFFICE, HOME
}
@Override
public String toString() {
return "Phone{" +
"id=" + id +
", type=" + type +
", number='" + number + '\'' +
'}';
}
}
2. Classe User
Agora veja a classe User
, a qual possui uma lista de Phones
. Desta forma, cada objeto User
vai poder conter uma lista de Phones
, já que existem três tipos possiveis de telefones a serem cadastrados.
Listagem 2. Classe User
package com.mballem.json.domain;
import java.io.Serializable;
import java.util.List;
/**
* Created by http://www.mballem.com/ on 09/02/2016.
*/
public class User implements Serializable {
private Integer id;
private String name;
private String email;
private List phones;
public User() {
super();
}
public User(Integer id, String name, String email, List phones) {
this.id = id;
this.name = name;
this.email = email;
this.phones = phones;
}
//getters/setters
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", phones=" + phones +
'}';
}
}
3. Classes para conversão
Como já conhecemos as classes de dominio, vamos desenvolver a parte do projeto referente ao conversão de dados. Para isto, criei uma interface nomeada como IConverter
– Listagem 3 – e esta interface foi implementada pela classe UserConverter
conforme Listagem 4.
Listagem 3. Interface IConverter
package com.mballem.json.converter;
import com.mballem.json.domain.User;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* Created by http://www.mballem.com/ on 09/02/2016.
*/
public interface IConverter {
void collectionToJson(String file, List entity) throws IOException;
List jsonToCollection(InputStream is) throws IOException;
}
O método collectionToJson()
recebe dois parâmetros, um String
que seria o caminho contendo o nome do arquivo JSON a ser gerado ao salvar uma lista de objetos Java. Já o segundo parametro é a própria lista a ser convertida e salva em um arquivo JSON.
No método jsonToCollection()
temos apenas um parametro do tipo InputStream
, o qual deve ser atribuido com local e nome o do arquivo JSON que será convertido em um objeto Java. Como este arquivo normalmente fica no classpath da aplicação, é aconselhavel usar o InputStream
para facilitar a localização.
Veja na Listagem 4 como é simples a implementação destes dois métodos. Ambos necessitam utilizar a classe ObjectMapper
da biblioteca Jackson, a qual é a classe central para se trabalhar no processo de conversão.
Listagem 4. Classe UserConverter
package com.mballem.json.converter;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.mballem.json.domain.User;
import java.io.*;
import java.util.List;
/**
* Created by http://www.mballem.com/ on 09/02/2016.
*/
public class UserConverter implements IConverter {
public void collectionToJson(String file, List users) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(new FileOutputStream(file), users);
}
public ListjsonToCollection(InputStream file) throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(file, new TypeReference<List>() {});
}
}
No método collectionToJson()
usamos o mapper
para acessar o método writeValue()
, o qual recebe dois parametros. O primeiro é um FileOutputStream
com a String
contendo o caminho e nome do arquivo de saída. Já o segundo parametro receber o objeto Java a ser convertido em um JSON, que neste caso é um lista do java.util.List
contendo um lista de objetos users
.
Agora, para converter um JSON em um objeto Java, temos o método jsonToCollection()
, o qual usa o mapper
para acessar o método readValue()
. Este método tem dois parametros e o primeiro recebe um objeto InputStream
. Já o segundo recebe o tipo Java para qual o arquivo deve ser convertido. Neste caso, usamos uma instancia da classe TypeReference
, do Jackson, passando como generico um objeto List
que é o objeto esperado após a conversão.
4. Executando o projeto
Por fim, vamos executar o projeto conforme o código da Listagem 5. Na classe JsonTutorial
temos dois métodos, o método main()
e o método fileLocation()
. O fileLocation()
serve apenas para carregar o arquivo contendo o conteúdo JSON que está no classpath da aplicação. Este arquivo está nomeado como users.json e está na pasta script no classpath. Veja um exemplo do arquivo em questão clicando aqui.
Listagem 5. Classe JsonTutorial
package com.mballem.json;
import com.mballem.json.converter.IConverter;
import com.mballem.json.converter.UserConverter;
import com.mballem.json.domain.Phone;
import com.mballem.json.domain.User;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by http://www.mballem.com/ on 09/02/2016.
*/
public class JsonTutorial {
private static final Logger logger = Logger.getLogger("JsonTutorial");
public static void main(String[] args) {
JsonTutorial jsonTutorial = new JsonTutorial();
IConverter converter = new UserConverter();
try {
//carrega o arquivo presente no classpath do projeto
InputStream is =
jsonTutorial.fileLocation("script/users.json");
List users = converter.jsonToCollection(is);
users.forEach(System.out::println);
//Local onde o arquivo será gravado
String file = "C:\\list.json";
converter.collectionToJson(file, users);
} catch (IOException ex) {
logger.log(Level.SEVERE, "ocorreu um erro", ex);
}
}
private InputStream fileLocation(String file) {
return getClass().getClassLoader().getResourceAsStream(file);
}
}
No método main()
vamos então executar a conversão do arquivo
users.json em uma lista de users
com o método jsonToCollection()
. Após converter o arquivo em uma lista, vamos exibir esta lista no console com um forEach()
.
User{id=1, name='Victor Rosa', email='victorrosa@email.com.br', phones=[Phone{id=1, type=MOBILE, number='91919911'}, Phone{id=2, type=OFFICE, number='32209911'}]}
User{id=2, name='Ricardo de Oliveira', email='ricardooli@email.com.br', phones=[Phone{id=3, type=MOBILE, number='91919922'}, Phone{id=4, type=HOME, number='32209922'}]}
//demais saídas omitidas
Em seguida, o método collectionToJson()
vai usar o próprio objeto users
, carregado a partir do arquivo, para gerar um novo arquivo com os dados, e assim, criar um arquivo de saída.