- gravar os dados dos objetos em um banco de dados e/ou arquivos,
- fazer a transmissão remota de objetos via rede.
Na serialização podem ser gravados os atributos públicos e privados para um stream. O processo inverso é chamado - deserialização, que consiste em restaurar os atributos de um objeto gravado em um stream.
Vamos considerar a seguinte classe:
/*
* Esta classe será utilizada para exemplo de serialização XML
* Notem que ela tem o formato de um bean
*
* Temos algumas propriedades: inteiro, string, boolean, array
*
*/
package serializacao;
/**
*
* @author Henrique
*/
public class ClasseSerializada1 {
/*
* Propriedade inteiro
*/
int i;
public int getInteiro() { return i; }
public void setInteiro(int i) { this.i = i; }
/*
* Propriedade minhaString
*/
String s;
public String getMinhaString() { return s; }
public void setMinhaString(String s) { this.s = s;}
/*
* Propriedade Array de inteiro
*/
int[] ia = new int[0];
public int[] getArrayInteiro() { return ia; }
public void setArrayInteiro(int[] iarray) {this.ia = iarray; }
/*
* Imprime as propriedades (usado no teste para vermos o que está no objeto)
*/ public void print() {
System.out.println(getInteiro());
System.out.println(getMinhaString());
int[] a = getArrayInteiro();
System.out.print("[");
for(int j = 0; j < a.length; j++) {
System.out.print(a[j]+" ");
}
System.out.println("]");
}
}
Notem que existem 3 propriedades públicas (encapsuladas com getters e setters).
Vamos criar uma outra classe para fazer a gravação e leitura. Notem que o processo é bastante parecido com a leitura e gravação de arquivos e por isto utilizamos Buffered___Stream e File___Stream.
O procedimento é bastante simples
- Fazemos (na escrita) o encadeamento de XMLEncoder(BufferedOutputStream(FileOutputStream))
- Usamos o XMLEncoder.writeObject para escrever o objeto no arquivo
Para ler é só fazer o inverso:
- chamar XMLDecoder(BufferedInputStream(FileInputStream))
- Usar XMLDecoder.readObject
- Prestar atenção que temos que fazer um cast da classe correta
/*
* classe para teste de funcionamento
*/
package serializacao;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
/**
*
* @author Henrique
*/
public class Serializacao1 {
/*
* A classe XMLEncoder serializa um objeto parecido com java.io.ObjectOutput
* --> é por isto que transferimos as streams para gerar o arquivo de
* O XMLEncoder somente persiste as propriedades públicas das classes
* Para cada propriedade pública, XMLEncoder chama o método getter
* (getPropriedade) correspondente e persiste o valor retornado
*
* Desta forma qualquer propriedade privada (que não possuir getter e setter)
* não será persistida ==> veremos isto em outro post
*/
public void serializar(String nomeArquivo, ClasseSerializada1 obj) {
try {
// Serializa o object no arquivo XML
XMLEncoder encoder;
encoder = new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream(nomeArquivo)));
encoder.writeObject(obj);
encoder.close();
} catch (FileNotFoundException e) {
// imprime erro na console
System.out.println(e.getMessage());
}
}
/*
* Na deserialização, um objeto criado é inicializado com os valores
* persistidos no arquivo XML (as propriedades públicas)
*
* le o arquivo serializado para dentro do objeto ClasseSerializada
* retorno o objeto lido do arquivo XML
*/
public ClasseSerializada1 deserializar(String nomeArquivo) {
ClasseSerializada1 obj = null;
try {
XMLDecoder decoder = new XMLDecoder(
new BufferedInputStream(
new FileInputStream(nomeArquivo)));
obj = (ClasseSerializada1) decoder.readObject();
decoder.close();
} catch (FileNotFoundException e) {
// imprime erro na console
System.out.println(e.getMessage());
}
return obj; // retorna o objeto lido do arquivo XML
}
}
Agora uma classe simples de teste.
/*
* classe para teste de funcionamento
*/
package serializacao;
/**
*
* @author Henrique
*/
public class TesteSerializacao {
/** * @param args the command line arguments
*/
public static void main(String[] args) {
static String nomeArquivoXML = "classeserializada.xml";
Serializacao1 s1 = new Serializacao1();
ClasseSerializada o = new ClasseSerializada();
// define as propriedades
o.setInteiro(1);
o.setMinhaString("Esta string será serializada");
o.setArrayInteiro(new int[]{1, 2, 3, 4});
// imprime para conferirmos os resultados
System.out.println("*************** Objeto criado");
o.print();
// grava (serializa) o objeto o
s1.serializar(nomeArquivoXML, o);
// faz alterações nos campos para podermos ver que
// a deserialização funciona
o.setInteiro(3);
o.setMinhaString("string alterada");
o.setArrayInteiro(new int[]{1, 2});
System.out.println("*************** Objeto alterado");
o.print(); // imprime o objeto alterado para vermos
// busca os dados a partir do arquivo XML
o = deserializar(nomeArquivoXML);
System.out.println("********** Objeto deserializado");
o.print(); // gera a mesma saída do primeiro o.print() deste método
}
}
O arquivo XML gerado está mostrado abaixo. Notem que a classe serializada está identificada (pacote + classe) e as propriedades estão todas listadas e identificadas.
<?xml version="1.0" encoding="UTF-8"?>
<java class="java.beans.XMLDecoder" version="1.7.0_07">
<object class="serializacao.ClasseSerializada">
<void property="arrayInteiro">
<array class="int" length="4">
<void index="0"> <int>1</int> </void>
<void index="1"> <int>2</int> </void>
<void index="2"> <int>3</int> </void>
<void index="3"> <int>4</int> </void>
</array>
</void>
<void property="inteiro">
<int>1</int>
</void>
<void property="minhaString">
<string>Esta string será serializada</string>
</void>
</object>
</java>
Vemos no próximo posto como impedir uma propriedade pública de ser serializada e como serializar uma propriedade privada.
Podemos tornar a classe Serializacao1 mais genérica, recebendo e devolvendo objetos da classe Object e fazendo o cast fora.
public class Serializacao {
public void serializar(String nomeArquivo, Object obj) {
... // fica tudo igual
}
public Object deserializar(String nomeArquivo) {
Object obj = null;
try {
XMLDecoder decoder = new XMLDecoder(
new BufferedInputStream(
new FileInputStream(nomeArquivo)));
obj = decoder.readObject();
decoder.close();
} catch (FileNotFoundException e) {
// imprime erro na console
System.out.println(e.getMessage());
}
return obj; // retorna o objeto lido do arquivo XML
}
}
No próximo post vamos usar este formato, ok?
Nenhum comentário:
Postar um comentário