quarta-feira, 24 de junho de 2015

O que é um listener ? Como fazer um ?

Olá amigos do Preciso Estudar Sempre, meu nome é João Paulo e minha paixão é estudar. O tema de hoje é de nível intermediário e para falar sobre ele precisamos entender o básico de programação e de Java Swing. Caso você não possua esses conhecimentos, recomendo que você volte aqui um pouco mais tarde.

Vamos aprender aqui o que são listeners e como construir um nosso. Se você já sabe o que é um listener, pule essa parte da explicação mas, se você não sabe, aperte seu cinto pois, a viagem está preste a começar.

Um listener é um ouvinte. Nesse momento, você pergunta: "Como assim um ouvinte?" Bem, vamos melhorar essa definição !

Um listener é uma estrutura programada que ouve eventos os quais, foram registrados para ele. Ainda não entendeu ? Quando eu digo ouvir, não quer dizer que uma orelha magicamente irá aparecer na sua tela. Quero dizer que uma parte de seu programa será acionada assim que um evento for realizado. Por evento, podemos imaginar clicks, focus em campos, retirada de focus em campos, parar o mouse em cima de algo, tirar o mouse de algo, mover o mouse, mudar um valor, entre outros. Vamos para um exemplo ?

Imagine a seguinte tela:
Figura 1 - Tela
Quando clicamos no botão "Confirmar", os dados da tela devem ser gravadas no banco de dados mas, como o botão consegue acionar o método que realiza a gravação no banco ? A resposta é: precisamos adicionar um listener de click àquele botão. Após adicionado, o listener conseguirá ouvir todos os eventos de click daquele ou de vários botões e realizará o processamento programado.

No Java Swing isso é feito da seguinte forma:

1 - Classe da tela.
 //construtor da tela  
 public Tela(){  
      initComponents();  
      MeuClickListener meuClickListener = new MeuClickListener();  
      jButton1.addActionListener(meuClickListener);  
 }  

2 - Classe que trata os eventos de click
 public class MeuClickListener implements ActionListener{  
      @Override  
      public void actionPerformed(ActionEvent e){  
      }  
 }  

Independente de estarmos na web, desktop, mobile ou na programação distribuída, os conceitos continuam o mesmo. Acima temos, o evento, o listener e a associação, respectivamente, o click, a classe MeuClickListener e a associação feita através da linha jButton1.addActionListener(meuClickListener);  

Espero que o conceito base de listener tenha ficado bastante claro na sua mente pois, agora iremos construir o nosso.

Siga os seguintes passos:

1 - Crie um projeto Java em sua IDE.

2 - Crie a interface Listener.

 public interface Listener {  
      public void receivedEvent(Event event);  
 }  

A interface Listener representa um listener geral, o qual trata um evento qualquer. Se quisermos listeners mais específicos, como por exemplo: ActionListener, WindowListener, podemos criar nossas próprias interfaces, com nossos próprios métodos.

3 - Crie a classe ListenerClick.

 public class ListenerClick implements Listener {  
      @Override  
      public void receivedEvent(Event event) {  
           System.out.println("Eu trato os eventos de click desse sistema.");  
           System.out.println("Dados do evento recebido: ");  
           System.out.println("Nome: " + event.getName());  
           System.out.println("Hash code do objeto que gerou o meu evento: " + event.getHashCodeOrigem());  
      }  
 }  

Precisamos criar uma implementação para o nosso listener porque é aqui que trataremos de fato os eventos (MeuClickListener).

4 - Crie a classe Event.

 public class Event {  
   private String name;  
   private int hashCodeOrigem;  
   public Event(String name) {  
     super();  
     this.name = name;  
   }  
   public String getName() {  
     return name;  
   }  
   public void setName(String name) {  
     this.name = name;  
   }  
      public int getHashCodeOrigem() {  
           return hashCodeOrigem;  
      }  
      public void setHashCodeOrigem(int hashCodeOrigem) {  
           this.hashCodeOrigem = hashCodeOrigem;  
      }  
 }  

Essa classe representa o evento mas, podemos criar nossas próprias classes de eventos, com atributos e métodos próprios.

5 - Crie a classe Dispatcher.

 import java.util.HashSet;  
 import java.util.Iterator;  
 import java.util.Set;  
 public class Dispatcher {  
   private static Dispatcher instance;  
   private Set<Listener> listeners;  
   private Dispatcher() {  
     this.listeners = new HashSet<Listener>();  
   }  
   public static Dispatcher getInstance() {  
     if (instance == null) {  
       instance = new Dispatcher();  
     }  
     return instance;  
   }  
   public void addListener(Listener listener) {  
     this.listeners.add(listener);  
   }  
   public void removeListener(Listener listener) {  
     this.listeners.remove(listener);  
   }  
   public void dispatchEvent(Event event) {  
     Iterator<Listener> iterator = listeners.iterator();  
     while (iterator.hasNext()) {  
       Listener listener = (Listener) iterator.next();  
       listener.receivedEvent(event);  
     }  
   }  
 }  

A classe Dispatcher é uma das classes mais importante porque é nela onde os listeners serão adicionados ou removidos. Os listeners adicionados são mantidos em uma lista para que sejam disparados mais tarde os métodos de tratamento de eventos.

6 - Crie a classe Main.

 public class Main {  
      private ListenerClick listenerClick = new ListenerClick();  
      public Main() {  
           Dispatcher.getInstance().addListener(listenerClick);  
      }  
      public static void main(String[] args) {  
           Main main = new Main();  
           Event eventoOnClick = new Event("represento um onClick");  
           eventoOnClick.setHashCodeOrigem(main.hashCode());  
           Dispatcher.getInstance().dispatchEvent(eventoOnClick);  
      }  
 }  

A classe Main é uma classe de exemplo, é onde botamos nosso listener para funcionar. Nessa classe instanciamos um listener de clicks, adicionamos esse listener no dispatcher e logo em seguida, disparamos um evento para todos os listeners registrados.

Notou que os mesmos passos que realizamos no Swing são os mesmos no nosso próprio sistema ? Instanciamos um listener, criamos um evento e adicionamos o listener. A única diferença do nosso sistema para o Java Swing, o qual está sendo usado como exemplo, é que o dispatch é feita pela própria classe do JButton e no nosso sistema precisamos realizar essa dispatch manualmente.

Sinta-se à vontade para modificar esse projeto a vontade, o objetivo desse post é passar a idéia básica dos listeners. A partir daí, você pode evoluir o quanto quiser a idéia.

Para baixar o projeto pronto, clique aqui.

Dúvidas !? Sugestões ?! Críticas ou elogios ?!

Deixe aí nos comentários ou na nossa página do facebook.


Referências:
Listener em Java - http://www.mews.com.br/dev/java/criando-listener-em-java/
Leia Mais ››

terça-feira, 16 de junho de 2015

Vamos fazer um chat ?

Olá amigos do Preciso Estudar Sempre, meu nome é João Paulo e minha paixão é estudar. O tema que estudaremos hoje é de nível avançado e para que possamos desenvolvê-lo, precisaremos antes entender o que são Sockets e Threads.

Se você já possui conhecimento sobre esses dois assuntos, pode baixar o projeto clicando aqui e seja feliz. :D

Maaaaaaaaaaaas, se você não sabe e quer saber, continue lendo este post, entenda o que explicarei, aí sim, baixe o projeto. Não recomendo baixar antes porque ter algo em mãos que não conseguimos entender não é tão legal.

O que é um Socket? O que um Socket faz ? Você já ouviu falar sobre isso ? Se você possui essa ou mais perguntas, relaxe, pegue um café, acenda um cigarro e confia no pai que, o inimigo cai.

Um socket é nada mais nada menos que, a ponta de uma comunicação de duas vias entre programas em uma rede de computadores. Ele é vinculado a uma porta de rede para que, a camada TCP possa identificar a aplicação que, destina dados para alguma outra aplicação.

Fácil, não !?

Você lendo isso e pirando: "Ainnn João, ainda não entendi, tem como dar um exemplo?"

Bem, vamos lá ! Vamos imaginar a seguinte: Você está digitando seu texto em seu editor de texto que você mais ama no mundo e precisar imprimir ele. O que acontece quando você clica no ícone de imprimir ?

O seu editor de texto cria um socket para a impressora, onde ele passa o ip e a porta para o socket e se conecta. Depois de conectado, ele envia os dados para a impressão. A impressora, por sua parte, já espera conexões. Ela realiza essa espera ouvindo uma porta de rede. Qualquer requisição feita para essa porta, será ouvida por ela onde, ela aceitará ou não essa conexão.

Então, se você entendeu o que eu escrevi aí em cima, você já tá "por dentro" do que é um socket. Vamos entender as threads ?

As threads são mais fácies ainda. Uma thread é um fluxo de dados executado de forma paralela junto ao processo que originou-o, por exemplo: Você já notou naquela barrinha de carregar quando você abre um programa? Aquela barra representa o progresso da inicialização do programa. Nessa inicialização, uma thread é iniciada para processar dados necessários que o programa precisará após ter sido carregado. Desta forma, há uma melhora na performance do programa. Tente imaginar o quanto o programa ficaria mais lento se ele não pudesse executar mais de uma tarefa por vez ?

Poxa que legal !!! Já entendemos os dois conceitos básicos para construir um chat. Agora vamos entender como um chat funciona e depois disso listar o que precisamos.

Para que um chat possa funcionar precisamos de clientes, um servidor, sockets, threads e canais de comunicação.
Figura 1 - Arquitetura do chat
Os cliente são as pessoas se falando onde, cada um possuirá sua própria tela de chat a qual, construiremos adiante. Cada cliente não tem noção de quantas pessoas estão no chat e para qualquer mensagem enviada, todos são notificados. O servidor é um programa que armazena todos os cliente conectados à ele e recebe todas as mensagens e redireciona as mesmas para todos, até para quem enviou. Isto é feito para que, o remetente de uma mensagem possa ver o que enviou.

Para que um cliente possa se conectar a um servidor, ele abre um socket e executa todo o processo explicado acima. Após a conexão ter sido feita, tanto o cliente quanto o servidor podem possuir controle sobre os fluxos de dados visando ler ou escrever dados.

Para sair da teoria e ir para a prática, vamos precisar de:
  • JDK instalado
  • Netbeans (estou usando a versão 7.4)
IMPORTANTE: Nosso chat será desenvolvido utilizando a tecnologia Java Swing. Se você não está familiarizado com ela, recomendo fortemente que você estude primeiro e depois volte pra cá porque, não explicarei Swing aqui.

IMPORTANTE: O layout das telas foi desenvolvido no Netbeans. Caso você queira importar o projeto daqui para o Eclipse, não recomendo logo, poderei ajudar.

Mãos na massa !

1 - Crie uma pasta em algum local de preferência sua.

2 - Abra o Netbeans e crie os projetos Cliente e Servidor na pasta recém criada. 

3 - Crie a classe Servidor no projeto Servidor.
package servidor;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 *
 */
public class Servidor {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        List<PrintStream> clientes = new ArrayList<>();
        
        try {
            ServerSocket server = new ServerSocket(3306);
            Socket socket;

            while (true) {
                socket = server.accept();
                /*registro dos clientes*/
                clientes.add(new PrintStream(socket.getOutputStream()));
                new EnviadorMensagem(socket, clientes).iniciarMensagens();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
    
}

Neste momento vamos focar somente bloco try. Lembra que eu expliquei lá em cima que o servidor (impressora) fica esperando conexões em uma determinada porta ? Então, o nosso não será diferente. Nosso servidor esperará conexões na porta 3306. Se você já trabalhou com MySQL, sabe que esta porta é utilizada por ele. Utilizei ela para que não precisasse abrir uma nova porta no meu roteador e é esse o jump of the cat (pulo do gato). Se você quiser fazer isso também é fácil, é só parar o serviço do MySQL.

Construímos esse loop infinito para que ele aguarde por infinitas conexões. Geralmente, loops infinitos consomem muita CPU mas, esse não será o nosso caso pois, o Servidor fica parado na primeira linha do loop onde, ele espera a conexão. Logo após da conexão ter sido estabelecida, o loop continua.

4 - Crie a classe Cliente no projeto Cliente.
package cliente;
import javax.swing.JOptionPane;

/**
 *
 */
public class Cliente {
    public static void main(String[] args) {
        while (true) {            
            String nomeCliente = JOptionPane.showInputDialog(null, "Informe seu nome", "Configurações iniciais", JOptionPane.INFORMATION_MESSAGE);
            if(nomeCliente == null || nomeCliente != null && "".equalsIgnoreCase(nomeCliente.trim())){
                JOptionPane.showMessageDialog(null, "O campo de nome do cliente é obrigatório.", "Dados obrigatórios", JOptionPane.ERROR_MESSAGE);
            } else {
                Chat chat = new Chat(nomeCliente);
                chat.setVisible(true);
                break;
            }
        }
    }
}

Essa classe é de fácil entendimento e eu dispenso explicações.

5 - Crie a classe Chat, no projeto Cliente e desenvolva a seguinte tela.
Figura 2 - Protótipo da Tela
6 - Crie a conexão com o servidor no construtor da classe Chat.
    public Chat(String nomeCliente) {
        initComponents();
        this.nomeCliente = nomeCliente;
        try {
            socket = new Socket("127.0.0.1", 3306);
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Não foi possível conectar ao servidor.", "Erro", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }
        jLabel1.setText(MessageFormat.format(jLabel1.getText(), nomeCliente));
        iniciarThread();
        this.escolherCor();
        this.configurarFonte();
        jTextArea1.requestFocus();
    }

No bloco try fazemos o que foi explicado no início desse post. O cliente está solicitando uma requisição ao servidor o qual, está no ip 127.0.0.1 (localhost) e na porta 3306. Vamos entender agora o método iniciarThread().

private void iniciarThread(){
        this.thread = new Thread(new Runnable() {
            String mensagemServidor;
            @Override
            public void run() {
                try {
                    inputStreamReader = new InputStreamReader(socket.getInputStream());
                    bufferedReader = new BufferedReader(inputStreamReader);
                    entrarSala();
                    while((mensagemServidor=bufferedReader.readLine())!=null){
                        try {
                            int indiceColchetes2 = mensagemServidor.indexOf("],[");
                            String message = mensagemServidor.substring(mensagemServidor.indexOf('[')+1,indiceColchetes2);
                            mensagemServidor = mensagemServidor.substring(indiceColchetes2+2);
                            Integer color = Integer.valueOf(mensagemServidor.substring(1,mensagemServidor.indexOf(']')));
                            StyleConstants.setForeground(styleNomeCliente, new Color(color));
                            styledDocument.insertString(styledDocument.getLength(), message + "\n", styleNomeCliente);
                        } catch (BadLocationException ex) {
                            ex.printStackTrace();
                        }
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
        thread.start();      
    }

Como o próprio nome já diz, esse método abre uma thread mas, para que precisamos dela ? Lembra o que falei sobre a execução paralela de tarefas ? Então, precisamos nesse momento executar de forma paralela, junto com a inicialização da tela, a abertura da stream de leitura do cliente para o servidor visando, ouvir as mensagens que o servidor envia para o cliente. De aonde conseguimos o input stream dessa comunicação cliente/servidor ? Do socket, obviamente. Senão fizéssemos tudo isso de forma paralela, a tela nunca abriria pois, o stream seria aberto e o programa iria ficar aguardando mensagens do servidor para o cliente.

7 - Crie o método que manda as mensagens para o chat e associe-o ao botão Enviar.
    private void enviarMensagem(){
        String mensagem = "["+nomeCliente + " diz: ";
        try {
            PrintStream printStream = new PrintStream(socket.getOutputStream());
            mensagem += jTextArea1.getText() + "],[" + this.corDaFonte.getRGB() + "]";
            printStream.println(mensagem);
            printStream.flush();
            jTextArea1.setText("");
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "Não foi possível enviar a mensagem.", "Erro", JOptionPane.ERROR_MESSAGE);
        }
    }

Neste método abrimos o stream de escrita do cliente para o servidor, adicionamos a mensagem nele e enviamos. Mais uma vez, aonde conseguimos o output stream para a escrita dos dados do cliente para servidor ? Do socket, mais uma vez.

8 - Encerre a conexão e saia do chat.
     private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            PrintStream printStream = new PrintStream(socket.getOutputStream());
            printStream.println("[[" + new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date()) + "] > " + nomeCliente + " saiu.],[" + this.corDaFonte.getRGB() + "]");
            printStream.flush();
            Thread.sleep(15);
            thread.stop();
            socket.close();
            System.exit(0);
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

Para sair do chat é necessário encerrarmos o socket e dar exit no programa. Eu encerrei a thread por uma questão de luxo mas, não é necessário. O sleep de 15 milisegundos é realizado porque antes do programa ser encerrado, o cliente envia uma mensagem para todos informando que saiu da sala. Caso o sleep não fosse feito, uma exception de escrita em socket seria propagada porque a velocidade do flush da stream é menor que a velocidade da execução do programa, ou seja, o flush não é imediato, ele demora um pouco.

9 - Cria a classe EnviadorMensagem no projeto Servidor.
package servidor;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.List;

/**
 *
 */
public class EnviadorMensagem {
    private Socket socket;
    private List<PrintStream> clientes;

    public EnviadorMensagem(Socket socket, List<PrintStream> clientes) {
        this.socket = socket;
        this.clientes = clientes;
    }
 
    public void iniciarMensagens(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                String mensagem = null;
                try {
                    InputStreamReader inputStreamReader = new InputStreamReader(socket.getInputStream());
                    BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                    while ((mensagem=bufferedReader.readLine()) != null) {              
                        enviarMensagem(mensagem);
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
        thread.start();
    }
 
    private void enviarMensagem(String mensagem){
        for(PrintStream cliente : clientes){
            cliente.println(mensagem);
            cliente.flush();
        }
    }
}

Nesta classe ouvimos as mensagens que os clientes nos mandam e escrevemos as mensagens para os clientes. Precisamos iniciar uma thread aqui pelo mesmo motivo que precisamos iniciar uma thread na classe Chat, execução paralela de tarefas.

É somente possível enviar as mensagens para todos os clientes porque na classe Servidor mantemos uma lista de quem está conectado no servidor. Então, para um novo cliente que entra no chat, é adicionado à lista o stream de escrita daquele cliente. Como a lista é passada por referência para o construtor da nossa classe, ela sempre estará atualizada.

Antes de terminar, fazer um checklist de tudo o que construímos ?
  1. Criação de projetos no Netbeans OK
  2. Criação da recepção de conexões no lado servidor. OK
  3. Criação da conexão do lado cliente. OK
  4. Criação da thread do lado cliente. OK
  5. Abertura dos streams de leitura e escrita do lado cliente. OK
  6. Encerramento do chat. OK
  7. Abertura dos streams de leitura e escrita do lado servidor. OK
Pronto, construímos os alicerces base para o nosso chat. Os pontos adicionais que você já deve ter notado como, formatação da fonte, entre outros, não abordarei aqui porque senão o post ficará mais extenso do que já está.

Para baixar o projeto, clique aqui. Caso você não tenha entendido algum ponto que eu não tenha deixado claro, deixe sua dúvida aí nos comentários.

Dúvidas !? Sugestões ?! Críticas ou elogios ?!

Deixe aí nos comentários ou na nossa página do facebook.

Facebook: https://www.facebook.com/precisoestudarsempre/

Referências:
What Is a Socket? - https://docs.oracle.com/javase/tutorial/networking/sockets/definition.html
Criando um chat com java (Parte 1) - https://www.youtube.com/watch?v=9__5MRYPVxc
Criando um chat com java (Parte 2) - https://www.youtube.com/watch?v=lqSEpj517Qc
Criando um chat com java (Parte 3) - https://www.youtube.com/watch?v=SzUZAvFFLI0
Leia Mais ››

sexta-feira, 5 de junho de 2015

Transformando XML em objetos Java com XStream

Olá amigos do Preciso Estudar Sempre, meu nome é João Paulo e minha paixão é estudar. Hoje falaremos sobre a transformação de XML em objetos Java. Para realizar essa transformação usaremos um framework chamado XStream. Esse framework facilita muito essa transformação, necessitando apenas de um Java Bean onde, a classe representará uma tag de maior nível e seus atributos representarão tag aninhadas.

Não entendeu !? Ficou confuso !? Calma, vou explicar melhor e vou explicar na prática.

Seeeeeee você está ansiosinho para fazer download do projeto, clique aqui.

Nossa situação é: precisamos ler de um arquivo XML os dados de um funcionário de uma empresa.

Para podermos trabalhar, precisaremos criar um projeto Maven. Não irei restringir qual tipo de projeto maven que você deve usar desde que, seja possível adicionar uma dependência no pom.xml e criar uma classe java.

Crie uma workspace e um projeto maven, adicione esta dependência no seu pom.xml.

 <dependency>  
      <groupId>com.thoughtworks.xstream</groupId> 
      <artifactId>xstream</artifactId> 
      <version>1.4.8</version> 
 </dependency> 

Crie o arquivo funcionario.xml em um lugar de preferência sua.

 <funcionario>  
      <nome>João Paulo</nome> 
      <email>meuemail@gmail.com</email> 
      <dtNascimento>28/03/1990</dtNascimento> 
      <cargo>Programador Java Senior</cargo> 
      <matricula>PGR 0001</matricula> 
      <telefones> 
           <telefone>2128906678</telefone> 
           <telefone>21988674322</telefone> 
           <telefone>21956099876</telefone> 
      </telefones> 
 </funcionario> 

Agora, crie a classe Funcionario.

 package XStreamProject.XStreamProject;  

 import java.util.Date; 
 import java.util.List; 

 public class Funcionario { 
      private String nome; 
      private String email; 
      private Date dtNascimento; 
      private String cargo; 
      private String matricula; 
      private List<Long> telefones; 

      public String getNome() { 
           return nome; 
      } 

      public void setNome(String nome) { 
           this.nome = nome; 
      } 

      public String getEmail() { 
           return email; 
      } 

      public void setEmail(String email) { 
           this.email = email; 
      } 

      public Date getDtNascimento() { 
           return dtNascimento; 
      } 

      public void setDtNascimento(Date dtNascimento) { 
           this.dtNascimento = dtNascimento; 
      } 

      public String getCargo() { 
           return cargo; 
      } 

      public void setCargo(String cargo) { 
           this.cargo = cargo; 
      } 

      public String getMatricula() { 
           return matricula; 
      } 

      public void setMatricula(String matricula) { 
           this.matricula = matricula; 
      } 

      public List<Long> getTelefones() { 
           return telefones; 
      } 

      public void setTelefones(List<Long> telefones) { 
           this.telefones = telefones; 
      } 
 } 

Crie a classe XMLToObject.java.

 package XStreamProject.XStreamProject;  

 import java.io.File; 
 import java.util.List; 
 import com.thoughtworks.xstream.XStream; 
 import com.thoughtworks.xstream.converters.basic.DateConverter; 

 public class XMLToObject { 

      public static void main(String[] args) { 
           new XMLToObject().transformXMLToObject(); 
      } 

      private void transformXMLToObject(){ 
           File nossoArquivoXML = new File("C://arquivos//funcionario.xml"); 
           XStream xStream = new XStream(); 

           /*configuracao*/ 
           xStream.alias("funcionario", Funcionario.class); 
           xStream.registerConverter(new DateConverter("dd/MM/yyyy", null)); 
           xStream.alias("telefones", List.class); 
           xStream.alias("telefone", Long.class); 
           Funcionario funcionario = (Funcionario) xStream.fromXML(nossoArquivoXML); 
           this.printReport(funcionario); 
      } 

      private void printReport(Funcionario funcionario){ 
           System.out.println("--- Relatório do funcionário ---"); 
           System.out.println("Nome: " + funcionario.getNome()); 
           System.out.println("Email: " + funcionario.getEmail()); 
           System.out.println("Data de nascimento: " + funcionario.getDtNascimento()); 
           System.out.println("Cargo: " + funcionario.getCargo()); 
           System.out.println("Matrícula: " + funcionario.getMatricula()); 
           if(!funcionario.getTelefones().isEmpty()){ 
                System.out.println("Telefones: "); 
                for (Long phone : funcionario.getTelefones()) { 
                     System.out.println("\t" + phone); 
                }           
           } 
      } 
 } 

Agora que já codificamos tudo, vamos entender o que escrevemos.

Nós temos três métodos, o primeiro é banal, é o nosso velho amigo main o qual, já conhecemos muito bem. O último método serve somente para imprimir os dados que foram obtidos através do XML, não devemos focar nossa atenção nele. Porém, o segundo método é o mais importante dos três e por isso foi deixado por último.

Nesse método criamos uma referência para o arquivo XML e instanciamos o XStream. Logo após isso, definimos os alias e registramos um converter. Os alias servem para dizer ao XStream que tipo é o dado que estamos tentando ler. Se isso não for feito, ele tentará atribuir uma String ao atributo mapeado o que, ocasionará em um erro de conversão. Não sei se você notou mas, mas os aliases só foram realizados nos dados que não são String.

O converter foi registrado porque, no XML a data de nascimento está no formato dd/MM/yyyy e o XStream não entende esse formato. Ele tem como formato padrão o yyyy-mm-dd hh:mm:ss e uma lista de padrões alternativos que seguem o padrão default. Se não tivéssemos registrado o converter, o XStream iria propagar um erro de conversão de dados.

Agora a parte mais importante de todo nosso estudo, a transformação dos dados. O XStream deixa isso muito simplificado através do método fromXML o qual, recebe a referência do nosso arquivo XML e usa as configurações feitas, ambas acima. O casting é feito porque esse método retorna um Object.

Pronto !! Você já tem tudo o que precisa para transformar dados de um XML em um objeto.

Para baixar o projeto, clique aqui.

Sugestões ?! Críticas ?! Elogios ?!

Deixe aí nos comentários ou na nossa página do facebook.


Referências:
Serializing Java Objects with XStream - http://www.xml.com/lpt/a/1462

Leia Mais ››