Java:Usando Objetos Serializados em Java
Ao serializar objetos em java, convertemos aquele "objeto/dado" em um conjunto de bytes que podem ser armazenados em um arquivo, para que posteriormente possamos utilizar os dados novamente como o objeto original.
Complexo!!! Mas vamos utilizar uma problema de negócio para explicar isso.
Resolvendo o Problema de negócio
Problema: Um Agência dos correios precisamos entregar 100 cartas rapidamente, sendo que a mesma tem 10 carteiros para executar o serviço?
Para resolvermos esse problema de distribuição criamos 3 classes;
- Carta = Objeto a ser serializado
- Distribuidor = Pega todas as cartas, classifica e distribui entre os carteiros.
- Ao classificarmos as cartas, crio o objeto Carta e serializo o mesmo para ser utilizado pelo Carteiro, armazenando o objeto no respectivo diretório do carteiro.
- Carteiro = Pega as respectivas cartas, no seu diretório e faz a entrega.
- O Carteiro pega o arquivo com o objeto e cria novamente o objeto Carta. Fazemos um print do Objeto.
Execução
Ao executarmos a classe Distribuidor
java Distribuidor
geramos os arquivos:
ls /tmp/Correios/00*/ /tmp/Correios/001/: A000.obj A001.obj A002.obj A003.obj A004.obj A005.obj A006.obj A007.obj A008.obj A009.obj A010.obj /tmp/Correios/002/: A011.obj A012.obj A013.obj A014.obj A015.obj A016.obj A017.obj A018.obj A019.obj A020.obj ... /tmp/Correios/009/: A081.obj A082.obj A083.obj A084.obj A085.obj A086.obj A087.obj A088.obj A089.obj A090.obj java Carteiro
Ao executarmos a classe Carteiro
java Carteiro
lemos os arquivos e entregamos (print) as cartas
Entrega Carta ... carta.getCep ...001 carta.getRemetente ...Fulano de Tal 010 Destinatario ...Ciclano da Silva 010 Destinatario ...Beltrano de Oliveira 010 carta.getConteudo ...Meus amigos .... Feliz Natal ... Entrega Carta ... carta.getCep ...001 carta.getRemetente ...Fulano de Tal Destinatario ...Ciclano da Silva Destinatario ...Beltrano de Oliveira carta.getConteudo ...Meus amigos .... Feliz Natal
Performance
No exemplo estou utilizando 100 Cartas para 1 Distribuidor e 10 Carteiros, mas este valor poderia ser 10 Milhões de Cartas ou mais. Para ter a performance que eu esperava da aplicação, executei diversas vezes a aplicação Carteiro. Exemplo:
java Carteiro 001 & java Carteiro 002 & ... java Carteiro 010 &
Dessa forma posso escalar muito a aplicação, com diversos Distribuidores e aumentar os Carteiros por Distribuidor.
Classes
Distribuidor.java
package net.ebasso; import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; public class Distribuidor { private static String outputCorreioDiretorio="/tmp/Correios"; private static int cartas = 100; public static void main(String[] args) { executaExemplo02(); } public static void executaExemplo02() { Distribuidor application = new Distribuidor(); try { String sufixo = ""; int j = 1; String carteiro = String.format("%03d", j); for (int i = 1; i < cartas; i++) { sufixo = String.format("%03d", i) ; ArrayList<String> destinatarios = new ArrayList<String>(); destinatarios.add("Ciclano da Silva " + sufixo); destinatarios.add("Beltrano de Oliveira " + sufixo); application.runOnce("A"+sufixo , carteiro,"Fulano de Tal " + sufixo, destinatarios, "Meus amigos .... Feliz Natal"); if ((i % 10) == 0) { j++; carteiro = String.format("%03d", j); } } } catch (Exception e) { e.printStackTrace(); } } // Executa para apenas 1 carta public static void executaExemplo01() { Distribuidor application = new Distribuidor(); try { ArrayList<String> destinatarios = new ArrayList<String>(); destinatarios.add("Ciclano da Silva"); destinatarios.add("Beltrano de Oliveira"); application.runOnce("A000","001","Fulano de Tal", destinatarios, "Meus amigos .... Feliz Natal"); } catch (Exception e) { e.printStackTrace(); } } private void runOnce(String messageId, String cep, String remetente, ArrayList<String> destinatarios, String conteudo ) throws Exception { // Criando a carta e definindo os valores Carta carta = new Carta(); carta.setMessageId(messageId); carta.setCep(cep); carta.setRemetente(remetente); carta.setConteudo(conteudo); carta.setDestinatarios(destinatarios); // Armazenando o objeto serializado String ojbFilename = outputCorreioDiretorio + "/" + cep + "/" + messageId + ".obj"; FileOutputStream arquivoAGravar = new FileOutputStream(ojbFilename); ObjectOutputStream objetoAGravar = new ObjectOutputStream(arquivoAGravar); objetoAGravar.writeObject(carta); objetoAGravar.flush(); objetoAGravar.close(); arquivoAGravar.close(); } }
Carteiro.java
package net.ebasso; import java.io.File; import java.io.FileInputStream; import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.Iterator; public class Carteiro { private static String inputCorreioDiretorio="/tmp/Correios"; public static void main(String[] args) { Carteiro application = new Carteiro(); try { String carteiroCep="001"; if (args.length > 0) { String carteiroCep = args[0]; } File folder = new File(inputCorreioDiretorio + "/" + carteiroCep); File[] listOfFiles = folder.listFiles(); for (int i = 0; i < listOfFiles.length; i++) { if (listOfFiles[i].isFile()) { String arquivo = listOfFiles[i].getName(); application.runOnce(arquivo, carteiroCep); } } } catch (Exception e) { e.printStackTrace(); } } private void runOnce(String messageId, String cep) throws Exception { String inputFilename = inputCorreioDiretorio + "/" + cep + "/" + messageId; FileInputStream arquivoALer = new FileInputStream(inputFilename); ObjectInputStream objetoALer = new ObjectInputStream(arquivoALer); // Criando a carta e definindo os valores Carta carta = (Carta) objetoALer.readObject(); objetoALer.close(); arquivoALer.close(); System.out.println("Entrega Carta ..."); System.out.println(""); System.out.println("carta.getCep ..." + carta.getCep()); System.out.println("carta.getRemetente ..." + carta.getRemetente()); ArrayList<String> destinatarios = carta.getDestinatarios(); Iterator<String> iterator = destinatarios.iterator(); while (iterator.hasNext()) { String destinatario = (String) iterator.next(); System.out.println("Destinatario ..." + destinatario); } System.out.println(""); System.out.println("carta.getConteudo ..." + carta.getConteudo()); } }
Carta.java
package net.ebasso; import java.io.Serializable; import java.util.ArrayList; public class Carta implements Serializable{ private static final long serialVersionUID = 3818318077429278285L; private String messageId; private String cep; private String remetente; private ArrayList<String> destinatarios; private String conteudo; public String getMessageId() { return messageId; } public void setMessageId( String messageId) { this.messageId = messageId; } public String getCep() { return cep; } public void setCep( String cep) { this.cep = cep; } public String getRemetente() { return remetente; } public void setRemetente( String remetente) { this.remetente = remetente; } public String getConteudo() { return conteudo; } public void setConteudo( String conteudo) { this.conteudo = conteudo; } public ArrayList<String> getDestinatarios() { return destinatarios; } public void setDestinatarios( ArrayList<String> destinatarios) { this.destinatarios = destinatarios; } }