Programação
eXtreme Go Horse (XGH)
15/01/10
Reblogando um post sensacional achado em http://gohorseprocess.wordpress.com.
Todas as vezes que eu leio esse post eu me identifico mais com os projetos que eu participo. Acredito que até daria para fazer uma eXtreme Go Horse Plus Plus (XGH++).
Parabéns ao criador!
1- Pensou, não é XGH.
XGH não pensa, faz a primeira coisa que vem à mente. Não existe segunda opção, a única opção é a mais rápida.
2- Existem 3 formas de se resolver um problema, a correta, a errada e a XGH, que é igual à errada, só que mais rápida.
XGH é mais rápido que qualquer metodologia de desenvolvimento de software que você conhece (Vide Axioma 14).
3- Quanto mais XGH você faz, mais precisará fazer.
Para cada problema resolvido usando XGH, mais uns 7 são criados. Mas todos eles serão resolvidos da forma XGH. XGH tende ao infinito.
4- XGH é totalmente reativo.
Os erros só existem quando aparecem.
5- XGH vale tudo, só não vale dar o toba.
Resolveu o problema? Compilou? Commit e era isso.
6- Commit sempre antes de update.
Se der merda, a sua parte estará sempre correta.. e seus colegas que se fodam.
7- XGH não tem prazo.
Os prazos passados pelo seu cliente são meros detalhes. Você SEMPRE conseguirá implementar TUDO no tempo necessário (nem que isso implique em acessar o BD por um script malaco).
8- Esteja preparado para pular fora quando o barco começar a afundar… ou coloque a culpa em alguém ou algo.
Pra quem usa XGH, um dia o barco afunda. Quanto mais o tempo passa, mais o sistema vira um monstro. O dia que a casa cair, é melhor seu curriculum estar cadastrado na APInfo, ou ter algo pra colocar a culpa.
9- Seja autêntico, XGH não respeita padrões.
Escreva o código como você bem entender, se resolver o problema, commit e era isso.
10- Não existe refactoring, apenas rework.
Se der merda, refaça um XGH rápido que solucione o problema. O dia que o rework implicar em reescrever a aplicação toda, pule fora, o barco irá afundar (Vide Axioma 8).
11- XGH é totalmente anárquico.
A figura de um gerente de projeto é totalmente descartável. Não tem dono, cada um faz o que quiser na hora que os problemas e requisitos vão surgindo (Vide Axioma 4).
12- Se iluda sempre com promessas de melhorias.
Colocar TODO no código como uma promessa de melhoria ajuda o desenvolvedor XGH a não sentir remorso ou culpa pela cagada que fez. É claro que o refactoring nunca será feito (Vide Axioma 10).
13- XGH é absoluto, não se prende à coisas relativas.
Prazo e custo são absolutos, qualidade é totalmente relativa. Jamais pense na qualidade e sim no menor tempo que a solução será implementada, aliás… não pense, faça!
14- XGH é atemporal.
Scrum, XP… tudo isso é modinha. O XGH não se prende às modinhas do momento, isso é coisa de viado. XGH sempre foi e sempre será usado por aqueles que desprezam a qualidade.
15- XGH nem sempre é POG.
Muitas POG’s exigem um raciocínio muito elevado, XGH não raciocina (Vide Axioma 1).
16- Não tente remar contra a maré.
Caso seus colegas de trabalho usam XGH para programar e você é um coxinha que gosta de fazer as coisas certinhas, esqueça! Pra cada Design Pattern que você usa corretamente, seus colegas gerarão 10 vezes mais código podre usando XGH.
17- O XGH não é perigoso até surgir um pouco de ordem.
Este axioma é muito complexo, mas sugere que o projeto utilizando XGH está em meio ao caos. Não tente por ordem no XGH (Vide Axioma 16), é inútil e você pode jogar um tempo precioso no lixo. Isto fará com que o projeto afunde mais rápido ainda (Vide Axioma 8). Não tente gerenciar o XGH, ele é auto suficiente (Vide Axioma 11), assim como o caos.
18- O XGH é seu brother, mas é vingativo.
Enquanto você quiser, o XGH sempre estará do seu lado. Mas cuidado, não o abandone. Se começar um sistema utilizando XGH e abandoná-lo para utilizar uma metodologia da moda, você estará fudido. O XGH não permite refactoring (vide axioma 10), e seu novo sistema cheio de frescurites entrará em colapso. E nessa hora, somente o XGH poderá salvá-lo.
19- Se tiver funcionando, não rela a mão.
Nunca altere, e muito menos questione um código funcionando. Isso é perda de tempo, mesmo porque refactoring não existe (Vide Axioma 10). Tempo é a engrenagem que move o XGH e qualidade é um detalhe desprezível.
20- Teste é para os fracos.
Se você meteu a mão num sistema XGH, é melhor saber o que está fazendo. E se você sabe o que está fazendo, vai testar pra que? Testes são desperdício de tempo, se o código compilar, é o suficiente.
21- Acostume-se ao sentimento de fracasso iminente.
O fracasso e o sucesso andam sempre de mãos dadas, e no XGH não é diferente. As pessoas costumam achar que as chances do projeto fracassar utilizando XGH são sempre maiores do que ele ser bem sucedido. Mas sucesso e fracasso são uma questão de ponto de vista. O projeto foi por água abaixo mas você aprendeu algo? Então pra você foi um sucesso!
22- O problema só é seu quando seu nome está no Doc da classe.
Nunca ponha a mão numa classe cujo autor não é você. Caso um membro da equipe morra ou fique doente por muito tempo, o barco irá afundar! Nesse caso, utilize o Axioma 8.
Fonte: http://gohorseprocess.wordpress.com/extreme-go-horse-xgh/
Apostila de Ruby on Rails da Caelum liberada para download
15/12/09
No último dia 12/12/2009, a Caelum liberou gratuitamente a apostila utilizada por eles nos cursos de Ruby on Rails. Para quem está começando, vale muito a pena fazer o download para estudo.
Para fazer o download, clique aqui.
Link direto para o PDF aqui.
A apostila é muito completa. É abordado desde os conceitos básico da programação em Ruby até o uso de gems, plugins e AJAX no Rails. É um bom pontapé de início essa apostila.
Abaixo segue o índice da apostila para você ter uma noção do que irá encontrar.
1 Agilidade na Web 1
1.1 A agilidade
1.2 A comunidade Rails
1.3 Bibliografia
1.4 Tirando dúvidas
1.5 Para onde ir depois?
2 A linguagem Ruby 4
2.1 A história do Ruby
2.2 Características
2.3 Instalação do interpretador
2.4 Outras implementações
2.5 MagLev
2.6 Ruby Enterprise Edition
2.7 Interactive Ruby
2.8 Tipos Básicos
2.9 Para Saber Mais – Desafios
2.10 Para Saber Mais – Desafio
3 Ruby Avançado 12
3.1 Mundo orientado a objetos
3.2 Métodos comuns
3.3 Meta-programação
3.4 Definição de métodos
3.5 Discussão: Enviando mensagens aos objetos
3.6 Classes
3.7 Desafio: Classes abertas
3.8 self
3.9 Desafio: self e o método puts
3.10 Atributos e propriedades: acessores e modificadores
3.11 Syntax Sugar
3.12 Métodos de Classe
3.13 Para saber mais: Singleton Classes
3.14 Metaprogramação
3.15 Convenções
3.16 Coleções
3.17 Blocos e Programação Funcional
3.18 Desafio: Usando blocos
3.19 Mais OO
3.20 Modulos
3.21 Manipulando erros e exceptions
3.22 Exercício: Manipulando exceptions
3.23 Arquivos Ruby
4 Ruby on Rails 29
4.1 Ruby On Rails – Apresentação
4.2 Aprender Ruby?
4.3 RadRails 30
4.4 Primeira Aplicação
4.5 Exercícios: Iniciando o Projeto
4.6 Estrutura dos diretórios
4.7 O Banco de Dados
4.8 Exercícios: Criando o banco de dados
4.9 A base da construção: scaffold (andaime)
4.10 Exercícios: Scaffold
4.11 Gerar as tabelas
4.12 Versão do Banco de Dados
4.13 Exercícios: Migrar tabela
4.14 Server
4.15 Documentação do Rails
4.16 Exercício Opcional: Utilizando a documentação
5 Active Record
5.1 Motivação
5.2 Exercícios: Controle de Restaurantes
5.3 Modelo – O “M” do MVC
5.4 ActiveRecord
5.5 Rake
5.6 Criando Modelos
5.7 Migrations
5.8 Exercícios: Criando os modelos
5.9 Manipulando nossos modelos pelo console
5.10 Exercícios: Manipulando registros
5.11 Exercícios Opcionais
5.12 Finders
5.13 Exercícios: Buscas dinâmicas
5.14 Validações
5.15 Exercícios: Validações
5.16 Exercícios – Completando nosso modelo
5.17 O Modelo Qualificação
5.18 Exercícios – Criando o Modelo de Qualificação
5.19 Relacionamentos
5.20 Para Saber Mais: Cache
5.21 Exercícios – Relacionamentos
5.22 Para Saber Mais – Eager Loading
5.23 Para Saber Mais – Named Scopes
5.24 Para Saber Mais – Modules
6 Controllers e Views
6.1 O “V” e o “C” do MVC
6.2 Hello World
6.3 Exercícios: Criando o controlador
6.4 Redirecionamento de Action e Action padrão
6.5 Trabalhando com a View: O ERB
6.6 Entendendo melhor o CRUD
6.7 Exercícios: Controlador do Restaurante
6.8 Helper
6.9 Exercícios: Utilizando helpers para criar as views
6.10 Partial
6.11 Exercícios: Customizando o cabeçalho
6.12 Layout
6.13 Exercícios: Criando o header
6.14 Outras formas de gerar a View
6.15 Filtros
7 Rotas
7.1 routes.rb
7.2 Pretty URLs
7.3 Named Routes
7.4 REST – map.resource
7.5 Actions extras em Resources
7.6 Diversas Representações
7.7 Para Saber Mais – Nested Resources
8 Completando o Sistema
8.1 Exercícios
8.2 Selecionando Clientes e Restaurante no form de Qualificações
8.3 Exercícios
8.4 Exercícios Opcionais
9 Calculations
9.1 Método
9.2 Média
9.3 Exercícios
10 Associações Polimórficas
10.1 Nosso problema
10.2 Alterando o banco de dados
10.3 Exercícios
11 Ajax fácil com RJS
11.1 Adicionando comentários nas views
11.2 Métodos de RJS Templates
11.3 Exercícios
11.4 Adicionando comentários
11.5 Exercícios
11.6 Exercícios – Enviando os dados com Ajax
12 Alguns Plugins e Gems Importantes
12.1 Paginação
12.2 Exercícios – Título
12.3 Hpricot
12.4 Exercícios – Testando o Hpricot
12.5 File Uploads: Paperclip
12.6 Exercícios
13 Apêndice A – Testes 127
13.1 O Porquê dos testes?
13.2 Test::Unit
13.3 RSpec
13.4 Cucumber, o novo Story Runner
14 Apêndice B – Integrando Java e Ruby
14.1 O Projeto
14.2 Testando o JRuby
14.3 Exercícios
14.4 Testando o JRuby com Swing
15 Apêndice C – Deployment
15.1 Webrick
15.2 CGI
15.3 FCGI – FastCGI
15.4 Lighttpd e Litespeed
15.5 Mongrel
15.6 Proxies Reversos
15.7 Phusion Passenger (mod_rails)
15.8 Ruby Enterprise Edition
15.9 Exercícios: Deploy com Apache e Passenger
16 Apêndice D – Instalação
16.1 Ruby – Ubuntu
16.2 Ruby – Windows
16.3 Rails
16.4 JDK
16.5 Aptana
16.6 Mongrel
16.7 MySQL
16.8 SVN
Verificando finais de semana em Java
08/09/09
Pessoal,
Seguem dois métodos simples que utiliza a API Calendar do JAVA para detectar os finais de semana de um determinado mês. Os dias dos mês que são finais de semana são colocados em uma List e retornados pelo método. Já me quebrou muitos galhos esses métodos.
Lembrando que em Calendar, o mês 01 (janeiro) começa com o valor 0.
O código abaixo está dividido em dois métodos. Há o isFinaDeSemana() que a partir de um dia, mês e ano, te devolve se é ou não um final de semana. O outro método getFinaisDeSemanaMes() te devolve uma list com todos os dias que são finais de semana em um mês.
private List getFinaisDeSemanaMes(int ano, int mes) { Calendar calendar = new GregorianCalendar(ano, mes - 1, 1); int diasMaximos = calendar.getMaximum(Calendar.DAY_OF_MONTH); int dia = 1; List finaisDeSemana = new ArrayList(); for (dia = 1; dia <= diasMaximos; dia++) { try { if (isFinalDeSemana(ano, mes, dia)) { finaisDeSemana.add(new Long(dia)); } } catch (Exception ex) { ex.printStackTrace(); continue; } } return finaisDeSemana; } private boolean isFinalDeSemana(int ano, int mes, int dia) throws Exception { if ((mes < 1) || (mes > 12)) { throw new Exception("Mês inválido"); } boolean finalDeSemana; mes = mes - 1; Calendar data = new GregorianCalendar(); data.set(ano, mes, 1); int diaMaximo = data.getActualMaximum(Calendar.DAY_OF_MONTH); if (diaMaximo < dia) { throw new Exception("Dia inválido"); } data.set(ano, mes, dia); int diaDaSemana = data.get(Calendar.DAY_OF_WEEK); if ((diaDaSemana == Calendar.SATURDAY) || (diaDaSemana == Calendar.SUNDAY)) { finalDeSemana = true; } else { finalDeSemana = false; } return finalDeSemana; }
Configurando ambiente de desenvolvimento C++ no Windows com Eclipse e MinGW
11/05/09
O Eclipse é uma das melhores IDEs de desenvolvimento Java no mercado. O que pouca gente sabe, é que ela também pode ser usada para desenvolvimento de aplicações utilizando o C++. Nesse pequeno tutorial, mostrarei como instalar o compilador C++ para Windows (MinGW) e utilizar o Eclipse para trabalhar com esse compilador.
O compilador MinGW (Minimalist GNU for Windows) é uma versão portada para Microsoft Windows do conjunto de ferramentas GNU. Este software inclui um conjunto de arquivos cabeçalho para a API do Windows que permite aos desenvolvedores usar o GCC para criar programas nativos em Windows sem precisar contar com uma emulação em tempo real de um sistema Unix-like.
Ambiente usado nesse tutorial:
- Windows XP SP2
- Eclipse 3.4 – Ganymede C++
O primeiro passo é baixar o Eclipse para C++. Para isso, vá ao site oficial do Eclipse (http://www.eclipse.org), clique em “Download Eclipse” e baixe a última versão do “Eclipse IDE for C/C++ Developers“. O Eclipse vem em uma pacote ZIP (quando Windows) com aproximadamento 68MB. Feito o download do Eclipse, descompacte o arquivo ZIP. Agora vamos ao próximo passo.
Nesse segundo passo, vamos baixar o MinGW, que é o compilador que utilizaremos. Acessem o site do MinGW (http://www.mingw.org), vá em “Downloads” e baixe a última versão do “Automated MinGW Installer“. Enquanto esse artigo esta sendo escrito, a última versão é a MinGW 5.1.4 de 26/04/2008. O arquivo é pequeno porque toda a instalação será feita online. Ele baixará todos os arquivos necessários na hora da instalação.
Existe alguns detalhes para se instalar o MinGW. Duplo clique no instalador e vamos começar a instalação. Você deverá estar conectado a Internet para instalar o MinGW com sucesso. Na primeira tela, clique em “Next“. Na segunda, marque a opção “Download and install“, igual na figura abaixo.
Depois clique em “I Agree” para aceitar a licensa GPL e na tela de escolha de pacote (Choose Package), marque a opção “Current“, para instalar a versão estável atual do MinGW.
- Previous: Versão estável anterior;
- Current: Versão atual estável;
- Candidate: Versão futura porém instável;
Na escolha de componentes (Choose Components), você deverá obrigatoriamente marcar as opções:
- MinGW base tools;
- g++ compiler
As outras opções (g77 compiler, Ada compiler…) são opcionais. Elas não são necessárias para o que pretendemos fazer com esse tutotial. Instale se você quiser.
Clique em “Next” e escolha o diretório de instalação. O diretório padrão e recomendado é o “C:\MinGW“. Avance mais uma vez e o instalador irá começar a fazer o download dos componentes e a instalação dos mesmos.
Após terminar, finalize o instalador e abra o Eclipse (que você descompactou no primeiro passo). Para rodar o Eclipse você irá precisar da JRE instalada. Caso você não tenha a JRE, basta fazer o download aqui: http://java.sun.com/javase/downloads/index.jsp. Selecione a opção: “Java SE Runtime Environment (JRE)“.
Com o Eclipse aberto, teremos a seguinte tela:
Até aí tudo certo? Agora vamos criar o nosso projetinho C++ de exemplo para ver se está tudo OK e se a compilação está funcionando. Para criar o projeto faça: “File > New > C++ Project“. Digite um nome para seu projeto e escolha a opção “Hello World C++ Project“. Verifique se o MinGW aparece no Toolchains. Abaixo segue uma figura para você ter uma referência:
Agora clique em “Finish” e vamos testar. O projeto será criado e você pode fechar essa tela de “Welcome” que aparece quando se inicia o Eclipse. Repare que o projeto criado está no lado esquerdo do Eclipse. Essa janela onde fica os projetos é chamada de “Project Explorer“. Expanda seu projeto, vá na pasta src e duplo clique no arquivo “Teste.cpp“. Você terá um código igual ao abaixo:
//============================================================================ // Name : Teste.cpp // Author : // Version : // Copyright : Your copyright notice // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> using namespace std; int main() { cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! return 0; }
Abaixo segue uma screenshot do Eclipse para você ter uma referência de como estarão as coisas nesse momento.
Agora vamos rodar o projeto. Para compilar e rodar esse projeto, clique no “Play” na barra de ferramentas lá em cima no Eclipse. Se tudo der certo, no console dele irá aparecer “!!!Hello World!!!“. Se aparecer, quer dizer que deu tudo certo e seu Eclipse está prontinho para ser usado como uma IDE de desenvovlimento C++.
Existem muitos livros e muitos tutoriais na Internet sobre C++. De uma pesquisada no Google sobre o assunto e você verá quanta informação você achará. Até a próxima e bons estudos.
Fontes:
Explicação sobre o MinGW: http://pt.wikipedia.org/wiki/MinGW
Problema do Rails 2.2.2 com o MySQL em Windows
10/03/09
Desde que a versão 2.2.2 do Rails foi lançada, alguns problemas relacionados ao driver do MySQL, que conectava a aplicação Rails ao banco, começaram a surgir e incharam lista de discussões com relatos de problemas. Um desses problemas era que quando vamos executar o rake db:migrate ocorre um erro que apresentava a seguinte mensagem:
!!! The bundled mysql.rb driver has been removed from Rails 2.2. Please install the mysql gem and try again: gem install mysql. rake aborted! 126: The specified module could not be found. - c:/ruby/lib/ruby/gems/1.8/gems/mysql-2.7.3-x86-mswin32/ext/mysql.so (See full trace by running task with --trace)
Acredito que se você tem esse problema você já deva ter instalado o gem do MySQL e mesmo assim continuou tendo esse problema. Caso você não tenha instalado o gem, por favor faça:
gem install mysql --no-rdoc --no-ri
Feita a instalação, veja se na lista de gems instaladas, se encontra o MySQL. Para ver suas gems instaladas:
gem list --local
O gem do MySQL deverá estar instalado.
Bem, se você tentar rodar o migrate denovo, provavelmente terá o mesmo problema. Pesquisando pelas partes mais distantes da internet encontrei uma solução que dizia para copiar e colar o arquivo <MYSQL_HOME>/bin/libmysql.dll para pasta <RUBY_HOME>/bin. Mas isso tem um porém. Se sua versão do MySQL instalado for a 5.1 o problema continuará.
Você terá que copiar o libmysql.dll do MySQL 5.0. No link abaixo você poderá fazer o download da versão correta do libmysql.dll pra usar:
http://instantrails.rubyforge.org/svn/trunk/InstantRails-win/InstantRails/mysql/bin/libmySQL.dll
Copie o libmysql.dll do link acima para a pasta <RUBY_HOME>/bin. Feito isso, tente novamente executar o migrate e verás que agora funciona!
Usando o XStream para serializar e desserializar objetos Java para XML
06/03/09
O XStream é uma biblioteca simples e poderosa que facilita muito nossa vida quando precisamos serializar objetos Java para arquivos XML e também para fazer o processo inverso. A partir de JavaBeans podemos escrever os XML com poucas linhas de código.
Nesse artigo o uso básico e o intermediário do XStream. Veremos como serializar e desserializar objetos, o uso de aliases e list.
O ambiente que usei para criar esse artigo foi o seguinte:
- Windows XP – SP3
- JDK 6
- Eclipse 3.4 – Ganymede
- XStream 1.3.1
Para começar, precisamos baixar a biblioteca para ser usada. Acessem o site oficial do XStream (http://xstream.codehaus.org), cliquem em “Download” e baixem a última versão da versão binária (Binary Distribution).
Depois de baixado, descompacte o arquivo e você verá diversos arquivos JARs. Não precisamos de todos, porém se quiser pode adicionar todos no classpath do seu projeto ou aqueles que mais se encaixarem em suas necessidades. No site do XStream tem uma explicação sobre cada uma das dependências opcionais. Acesse: http://xstream.codehaus.org/download.html.
Depois de adicionar os JARs no classpath, estamos prontos para começar a codificar. Nosso primeiro exemplo será serializar um objeto simples (JavaBean) para XML. Vamos criar esse objeto:
package com.meupost.beans; public class Agenda { private String nomePessoa; private int idade; private String email; private String telefone; private String fax; public String getNomePessoa() { return nomePessoa; } public void setNomePessoa(String nomePessoa) { this.nomePessoa = nomePessoa; } public int getIdade() { return idade; } public void setIdade(int idade) { this.idade = idade; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getTelefone() { return telefone; } public void setTelefone(String telefone) { this.telefone = telefone; } public String getFax() { return fax; } public void setFax(String fax) { this.fax = fax; } }
Beleza! O objeto é esse. Vamos mandar ele para um XML. No nosso exemplo faço a serialização direto no void main(). Vejam:
package com.meupost.main; import com.meupost.beans.Agenda; import com.thoughtworks.xstream.XStream; public class Main { public static void main(String args[]) { Agenda a1 = new Agenda(); a1.setEmail("amigo1@email.com.br"); a1.setFax("123-4567"); a1.setIdade(55); a1.setNomePessoa("Fernando Pessoa"); a1.setTelefone("654-3210"); XStream x = new XStream(); System.out.println(x.toXML(a1)); } }
A saída será assim:
<com.meupost.beans.Agenda> <nomePessoa>Fernando Pessoa</nomePessoa> <idade>55</idade> <email>amigo1@email.com.br</email> <telefone>654-3210</telefone> <fax>123-4567</fax> </com.meupost.beans.Agenda>
Muito bom. Mas agora vamos complicar mais um pouco. Vamos criar mais um objeto chamado Endereco que vai conter onde nosso indivíduo mora. Esse objeto Endereco entrará como atributo do objeto Agenda. Vejam o exemplo abaixo de como fica e o resultado do XML.
Objeto Endereco:
package com.meupost.beans; public class Endereco { private String rua; private int numero; private String cidade; private String estado; public String getRua() { return rua; } public void setRua(String rua) { this.rua = rua; } public int getNumero() { return numero; } public void setNumero(int numero) { this.numero = numero; } public String getCidade() { return cidade; } public void setCidade(String cidade) { this.cidade = cidade; } public String getEstado() { return estado; } public void setEstado(String estado) { this.estado = estado; } }
Objeto Agenda. Reparem que adicionamos o atributo Endereco!
package com.meupost.beans; public class Agenda { private String nomePessoa; private int idade; private String email; private String telefone; private String fax; private Endereco endereco; public String getNomePessoa() { return nomePessoa; } public void setNomePessoa(String nomePessoa) { this.nomePessoa = nomePessoa; } public int getIdade() { return idade; } public void setIdade(int idade) { this.idade = idade; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getTelefone() { return telefone; } public void setTelefone(String telefone) { this.telefone = telefone; } public String getFax() { return fax; } public void setFax(String fax) { this.fax = fax; } public Endereco getEndereco() { return endereco; } public void setEndereco(Endereco endereco) { this.endereco = endereco; } }
E agora o teste e resultado:
package com.meupost.main; import com.meupost.beans.Agenda; import com.meupost.beans.Endereco; import com.thoughtworks.xstream.XStream; public class Main { public static void main(String args[]) { Agenda a1 = new Agenda(); a1.setEmail("amigo1@email.com.br"); a1.setFax("123-4567"); a1.setIdade(55); a1.setNomePessoa("Fernando Pessoa"); a1.setTelefone("654-3210"); Endereco end = new Endereco(); end.setRua("Rua Saldanha Marinho"); end.setNumero(1234); end.setCidade("São José do Rio Preto"); end.setEstado("São Paulo"); a1.setEndereco(end); XStream x = new XStream(); System.out.println(x.toXML(a1)); } }
Ótimo. E por fim o XML gerado:
<com.meupost.beans.Agenda> <nomePessoa>Fernando Pessoa</nomePessoa> <idade>55</idade> <email>amigo1@email.com.br</email> <telefone>654-3210</telefone> <fax>123-4567</fax> <endereco> <rua>Rua Saldanha Marinho</rua> <numero>1234</numero> <cidade>São José do Rio Preto</cidade> <estado>São Paulo</estado> </endereco> </com.meupost.beans.Agenda>
Viram que dentro do nó endereco temos os atributos que definimos no nosso objeto? Pois bem, é assim que você pode relacionar os JavaBeans.
Vocês já devem ter percebido que o nome do nó raiz ta o mesmo nome do pacote. Isso com certeza é um incoveniente muito grande quando colocamos nosso sistema em produção. Para arrumarmos isso, podemos usar os Aliases que o XStream oferece. Basta uma linha de código. Vamos mudar nosso método void main() adicionando o alias e vamos gerar o XML novamente. Vejam:
package com.meupost.main; import com.meupost.beans.Agenda; import com.meupost.beans.Endereco; import com.thoughtworks.xstream.XStream; public class Main { public static void main(String args[]) { Agenda a1 = new Agenda(); a1.setEmail("amigo1@email.com.br"); a1.setFax("123-4567"); a1.setIdade(55); a1.setNomePessoa("Fernando Pessoa"); a1.setTelefone("654-3210"); Endereco end = new Endereco(); end.setRua("Rua Saldanha Marinho"); end.setNumero(1234); end.setCidade("São José do Rio Preto"); end.setEstado("São Paulo"); a1.setEndereco(end); XStream x = new XStream(); //Adicionei nova linha aqui! x.alias("agenda", Agenda.class); System.out.println(x.toXML(a1)); } }
E o resultado:
<agenda> <nomePessoa>Fernando Pessoa</nomePessoa> <idade>55</idade> <email>amigo1@email.com.br</email> <telefone>654-3210</telefone> <fax>123-4567</fax> <endereco> <rua>Rua Saldanha Marinho</rua> <numero>1234</numero> <cidade>São José do Rio Preto</cidade> <estado>São Paulo</estado> </endereco> </agenda>
Agora, vamos fazer o processo inverso. Ao invés de escrevermos o XML, vamos ler e criar os objeto a partir do XML. Para facilitar, vamos usar nossos objetos já criados (Agenda e Endereco). Abaixo há um exemplo onde crio um objeto String com o XML a ser lido, passo a String ao XStream e o próprio se encarrega de criar nossos objetos JavaBean de volta sem esforço nenhum.
package com.meupost.main; import com.meupost.beans.Agenda; import com.meupost.beans.Endereco; import com.thoughtworks.xstream.XStream; public class Main { public static void main(String args[]) { String xml; xml = "<agenda>" + "<nomePessoa>Angelina Jolie</nomePessoa>" + "<idade>35</idade>" + "<email>angelina@jolie.com</email>" + "<telefone>1742-5236</telefone>" + "<fax>6541-222</fax>" + "<endereco>" + ="<rua>Rubião Júnior</rua>" + "<numero>2104</numero>" + "<cidade>São José do Rio Preto</cidade>" + "<estado>São Paulo</estado>" + "</endereco>" + "</agenda>"; XStream x = new XStream(); x.alias("agenda", Agenda.class); Agenda a = (Agenda) x.fromXML(xml); System.out.println(a.getNomePessoa()); } }
Vejam que no exemplo acima eu precisei indicar qual a classe que o nó raiz “agenda” fazia parte. Depois foi só passar o XML para o XStream e fazer o Cast para obter o objeto. Por fim exibimos em console o nome da Angelina!
Agora mais um problema tanto para leitura quanto para escrita do XML. E quando temos várias informações dentro de um nó? Por exemplo, temos um XML precido com esse abaixo:
<agenda> <pessoas> <pessoa> <nomePessoa>Fernando Pessoa</nomePessoa> <idade>55</idade> <email>amigo1@email.com.br</email> <telefone>124-6984</telefone> <fax>654-3210</fax> <endereco> <rua>Rua Saldanha Marinho</rua> <numero>5110</numero> <cidade>São José do Rio Preto</cidade> <estado>São Paulo</estado> </endereco> </pessoa> <pessoa> <nomePessoa>felipao@email.com.br</nomePessoa> <idade>60</idade> <email>amigo1@email.com.br</email> <telefone>2310-1110</telefone> <fax>211-4100</fax> <endereco> <rua>Rua Francisco Glicério</rua> <numero>210</numero> <cidade>Campinas</cidade> <estado>São Paulo</estado> </endereco> </pessoa> <pessoa> <nomePessoa>Raul Seixas</nomePessoa> <idade>78</idade> <email>raulzito@email.com.br</email> <telefone>222-2222</telefone> <fax>111-1111</fax> <endereco> <rua>Rua Mar Vermelho</rua> <numero>450</numero> <cidade>Babilônia</cidade> <estado>São Paulo</estado> </endereco> </pessoa> </pessoas> </agenda>
Temos vários nós pessoa. Como se fosse uma lista de pessoas. E para tratarmos isso com o XStream? Temo como? Sim, lógico que tem. Primeiramente vamos criar o objeto (JavaBean) Pessoa contendo os mesmos atributos que havia no objeto Agenda, pois agora o objeto Agenda vai conter somente um atributo que é a lista de pessoas. Veja como fica o objeto Agenda e o objeto Pessoa:
Agenda:
package com.meupost.beans; import java.util.ArrayList; import java.util.List; public class Agenda { private List<Pessoa> pessoas = new ArrayList<Pessoa>(); public void add(Pessoa pessoa) { this.pessoas.add(pessoa); } public List<Pessoa> getContent() { return this.pessoas; } }
Pessoa:
package com.meupost.beans; public class Pessoa { private String nomePessoa; private int idade; private String email; private String telefone; private String fax; private Endereco endereco; public String getNomePessoa() { return nomePessoa; } public void setNomePessoa(String nomePessoa) { this.nomePessoa = nomePessoa; } public int getIdade() { return idade; } public void setIdade(int idade) { this.idade = idade; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getTelefone() { return telefone; } public void setTelefone(String telefone) { this.telefone = telefone; } public String getFax() { return fax; } public void setFax(String fax) { this.fax = fax; } public Endereco getEndereco() { return endereco; } public void setEndereco(Endereco endereco) { this.endereco = endereco; } }
Viram a diferença? Agora o objeto agenda possui uma List onde podemos ir adicionando o objeto Pessoa. O XStream ficará responsável de ler essa List e colocar no XML. Abaixo veja o exemplo de preenchimento dos objetos e o resultado depois que o XStream transforma para XML:
package com.meupost.main; import com.meupost.beans.Agenda; import com.meupost.beans.Endereco; import com.meupost.beans.Pessoa; import com.thoughtworks.xstream.XStream; public class Main { public static void main(String args[]) { Agenda a1 = new Agenda(); Pessoa p1 = new Pessoa(); p1.setEmail("amigo1@email.com.br"); p1.setFax("654-3210"); p1.setIdade(55); p1.setNomePessoa("Fernando Pesso"); p1.setTelefone("124-6984"); Endereco e1 = new Endereco(); e1.setRua("Rua Saldanha Marinho"); e1.setCidade("São José do Rio Preto"); e1.setNumero(5110); e1.setEstado("São Paulo"); p1.setEndereco(e1); Pessoa p2 = new Pessoa(); p2.setEmail("amigo1@email.com.br"); p2.setFax("211-4100"); p2.setIdade(60); p2.setNomePessoa("felipao@email.com.br"); p2.setTelefone("2310-1110"); Endereco e2 = new Endereco(); e2.setRua("Rua Francisco Glicério"); e2.setCidade("Campinas"); e2.setNumero(210); e2.setEstado("São Paulo"); p2.setEndereco(e2); Pessoa p3 = new Pessoa(); p3.setEmail("raulzito@email.com.br"); p3.setFax("111-1111"); p3.setIdade(78); p3.setNomePessoa("Raul Seixas"); p3.setTelefone("222-2222"); Endereco e3 = new Endereco(); e3.setRua("Rua Mar Vermelho"); e3.setCidade("Babilônia"); e3.setNumero(450); e3.setEstado("São Paulo"); p3.setEndereco(e3); a1.add(p1); a1.add(p2); a1.add(p3); XStream x = new XStream(); x.alias("agenda", Agenda.class); x.alias("pessoa", Pessoa.class); String xml = x.toXML(a1); System.out.println(xml); } }
E a nossa saída em XML:
<agenda> <pessoas> <pessoa> <nomePessoa>Fernando Pesso</nomePessoa> <idade>55</idade> <email>amigo1@email.com.br</email> <telefone>124-6984</telefone> <fax>654-3210</fax> <endereco> <rua>Rua Saldanha Marinho</rua> <numero>5110</numero> <cidade>São José do Rio Preto</cidade> <estado>São Paulo</estado> </endereco> </pessoa> <pessoa> <nomePessoa>felipao@email.com.br</nomePessoa> <idade>60</idade> <email>amigo1@email.com.br</email> <telefone>2310-1110</telefone> <fax>211-4100</fax> <endereco> <rua>Rua Francisco Glicério</rua> <numero>210</numero> <cidade>Campinas</cidade> <estado>São Paulo</estado> </endereco> </pessoa> <pessoa> <nomePessoa>Raul Seixas</nomePessoa> <idade>78</idade> <email>raulzito@email.com.br</email> <telefone>222-2222</telefone> <fax>111-1111</fax> <endereco> <rua>Rua Mar Vermelho</rua> <numero>450</numero> <cidade>Babilônia</cidade> <estado>São Paulo</estado> </endereco> </pessoa> </pessoas> </agenda>
Bem, estamos chegando quase no fim do artigo. Mostrei como usar o XStream para escrever XML e como ler. Ainda há muito o que aprender sobre o XStream como os aliases de campo (aliasField) e atributos. Mas esse artigo não irá se aprofundar tanto. Espero que com o que foi mostrado e ensinado aqui seja o suficiente para um início. Há um pouco de material de estudo no site do XStream, mas também é básico. O melhor mesmo é ir no Google ou mexer no JavaDoc do XStream (http://xstream.codehaus.org/javadoc/index.html).
Para praticar você pode usar diversas APIs disponíveis como o do YouTube, Mercado Livre, Yahoo… Esses XMLs são mais complexos e são ótimos para estudo.
Até a próxima!
Usando o Gmail para enviar e-mail com o ActionMailer no Rails
15/02/09
Existe uma maneira muito fácil de se enviar e-mails no Rails e usando o Gmail. Nesse pequeno tutorial tentarei explicar como fazer isso funcionar.
Primeiramente é preciso saber que o Gmail utiliza para autenticação de protocolo SMTP (envio de e-mails) o ssl/tls. Essa forma de autenticação não é suportada nativamente pelo ActionMailer. Isso quer dizer que precisaremos de uma ajudinha para podermos enviar e-mails utilizando o Rails e o Gmail.
Essa ajudinha é uma biblioteca que está voando pela Internet (eu não sei quem é o autor e muito menos da onde ela saiu) e nos ajudará com a autenticação. Eu tenho uma cópia dessa biblioteca em meu GitHub, você pode pegá-la aqui.
Com a biblioteca em mãos copie ela para a pasta lib do seu projeto Rails. Provavelmente ficará assim o caminho:
/lib/smtp_tls.rb
Agora abra o arquivo config/environment.rb e lá no fim, bem lá no fim mesmo, adicione o seguinte trecho de código:
ActionMailer::Base.default_content_type = "text/html" ActionMailer::Base.smtp_settings = { :address => "smtp.gmail.com", :port => 587, :authentication => :plain, :user_name => "seuemail@gmail.com", #Você pode usar o Google Apps! :password => 'suasenha' }
Bacana. Está tudo configurado. Agora vamos ver como se fazer no ActionMailer para se enviar um e-mail. Vamos gerar um novo Mailer. Em seu console digite:
ruby script/generate mailer Notificador
Seu novo mailer será gerado. Após a geração, abra ele (app/models/notificador.rb)
Adicione o seguinte método:
def notificar recipients "destinatario@email.com" from "meumail@meuemail.com" subject "Titulo do Email" end
Agora você precisa adicionar uma view com o mesmo nome desse método, assim como se faz com os Controllers. Nese caso, a vew ficaria views/teste/notificar.erb
Nesse arquivo ficará tudo o que você quer enviar ao destinatório. É o corpo do e-mail mesmo. Você pode utilizar variáveis de instância caso queira passar alguma informação para a view, da mesma forma que é feito nos controllers.
Criada a view, basta chamar o mailer nos controllerspara enviar o email da seguinte forma:
Notificador.deliver_notificarRepare que é colocado um deliver_ ali antes do nome do método que setamos. Isso é normal.
Se tudo ocorrer bem seu e-mail será enviado. Porém enviando um e-mail dessa forma irá ter um tempo de request mais demorado.
Obtendo Hash MD5 e SHA com Rails
14/02/09
Para se obter hashs tanto MD5 como SHA com Rails é muito fácil. Abaixo segue o que eu faço para calcular os Hashs:
def md5(str) return Digest::MD5.hexdigest(str) end def sha1(str) return Digest::SHA1.hexdigest(str) end def sha256(str) return Digest::SHA256.hexdigest(str) end
Você pode ver no exemplo acima que coloquei três funções. Uma para MD5, outra para SHA1 e outra para SHA256. Mas existem outros ainda. Veja:
- Digest::SHA1.hexdigest() – Produz 40 caracteres de dígitos hexadecimais.
- Digest::SHA256.hexdigest() – Produz 64 caracteres de dígitos hexadecimais.
- Digest::SHA384.hexdigest() – Produz 96caracteres de dígitos hexadecimais.
- Digest::SHA512.hexdigest() – Produz 128 caracteres de dígitos hexadecimais.
Se quiser, você pode testar essas funções no console do Rils. Basta abrir o console:
ruby script/consoleDigite o comando:
strHash = Digest::SHA1.hexdigest("string")
A saída deverá ser:
=> "ecb252044b5ea0f679ee78ec1a12904739e2904d"
Fácil e simples.
Serialização de objeto no Java
03/12/08
Quando estamos fazendo qualquer atividade no computador como um documento de texto, jogando um game ou até mesmo declarando o imposto de renda é quase que imperceptivel para nós a capacidade desses aplicativos salvarem informações no computador para que no futuro possamos continuar o trabalho de onde paramos. Mas o que isso tem haver com serialização de objetos no Java?
Bem, quando estamos codificando em Java, nossa aplicação também poderá salvar e recuperar informações no computador. Essas informações salvas, são salvas como objetos e essas mesmas informações salvas podem ser recuperadas para uso posterior pelo nosso programa.
Basicamente a serialização de objetos nos permite salvar em arquivo objetos para que no futuro nossa aplicação recupere esse objeto a partir do arquivo ou até mesmo uma outra aplicação poderá recuperar tal objeto. Diversas linguagens trabalham com serialização de objetos. Em um post futuro, tentarei explicar como funciona a serialização de objetos no Ruby.
A serialização de objetos no Java é simples e utiliza uma interface de marcação que é a java.io.Serializable. Essa interface não possui nenhum método. Ela só serve para marcar a classe que poderá ser serializada. Quando Java internamente olhar para essa classe e ver que ela implementa a java.io.Serializable, ele saberá que essa classe é certa para a serialização.
A serialização é boa para alguns casos e ruins para outros. Em classes onde há senhas, dados confidenciais ou qualquer tipo de informação que deva ser protegida a serialização pode ser perigosa pois ela “externa” essas informações. Portanto deverá haver muito cuidado na hora de se decidir o que deve ser serializado ou não.
Nesse post mostrarei de forma bem simples e organizada como serializar o objeto para arquivo, recuperar esse objeto e exibir em console os atributos do objeto que salvamos.
Primeiramente vamos criar um objeto que iremos salvar. Eu criei uma JavaBean que representa um carro.
package com.meupost.beans; import java.io.Serializable; public class Carro implements Serializable { private String cor; private String nome; private String marca; private float valor; public String getCor() { return cor; } public void setCor(String cor) { this.cor = cor; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } public String getMarca() { return marca; } public void setMarca(String marca) { this.marca = marca; } public float getValor() { return valor; } public void setValor(float valor) { this.valor = valor; } }
Feita a nossa classe que irá ser serializada, iremos criar outra classe que será responsável por serializar o objeto da classe acima. Essa classe que iremos criar agora é a classe fundamental na serialização de objetos no Java. Vejam:
package com.meupost.serial; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class Serializar { /** * Esse método recebe um objeto arquivo e o objeto que será serializado. * O método irá serializar o objeto passado no arquivo (referenciado pelo objeto file). */ public static void salvarObjeto(File file, Object objeto) throws FileNotFoundException, IOException { if (objeto == null) { throw new NullPointerException("Objeto passado é nulo"); } FileOutputStream fileOut = null; ObjectOutputStream objOut = null; try { fileOut = new FileOutputStream(file); objOut = new ObjectOutputStream(fileOut); objOut.writeObject(objeto); } catch (FileNotFoundException e) { throw new FileNotFoundException("O arquivo não pode ser encontrado"); } catch (IOException e) { throw new IOException("Erro de entrada e saída"); } finally { if (fileOut != null) { fileOut.close(); } if (objOut != null) { objOut.close(); } } } /** * Para ler o objeto serializado, nós somente precisamos no arquivo onde * esse objeto está salvado. * Sabendo o arquivo, nós conseguimos recuperar o objeto tranquilamente. */ public static Object recuperarObjeto(File file) throws FileNotFoundException, IOException, ClassNotFoundException { Object obj = null; if (file == null) { throw new NullPointerException("Objeto FILE é Nulo."); } FileInputStream fileIn = null; ObjectInputStream objIn = null; try { fileIn = new FileInputStream(file); objIn = new ObjectInputStream(fileIn); obj = objIn.readObject(); } catch (FileNotFoundException e) { throw new FileNotFoundException("Arquivo não encontrado"); } catch (IOException e) { throw new IOException("Erro de entrada e saída"); } catch (ClassNotFoundException e) { throw new ClassNotFoundException("Erro ao recuperar objeto do arquivo"); } finally { if (fileIn != null) { fileIn.close(); } if (objIn != null) { objIn.close(); } } return obj; } }
Com essa classe pronta, nós estamos apto a serializar o nosso objeto. Assim, vamos criar a classe Main para que nós possamos testar se nossa serialização irá funcionar o não. Na classe Main nós iremos instanciar alguns objetos Carro, colocaremos esses objetos em uma List e salvaremos essa List usando a nossa classe Serializar.
Depois de serializado, nós iremos recuperar essa List e iremos iremos percorrer essa lista mostrando os objetos que foram salvo. Eu criei um método que preenche a lista com objetos carro para ficar mais organizado.
package com.meupost.main; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.meupost.beans.Carro; import com.meupost.serial.Serializar; public class Main { /** * Na classe Main iremos testar nossa serialização. Vamos serializar uma lista * de objetos Carro. */ public static void main(String[] args) { String path = "C:\Documents and Settings\ricardo\Desktop\objeto.ser"; File file = new File(path); try { List<Carro> lstCarros = preencherLista(); Serializar.salvarObjeto(file, lstCarros); System.out.println("Objetos salvos com Sucesso!"); List<Carro> novaLista = (List) Serializar.recuperarObjeto(file); System.out.println("Objetos Recuperados com sucesso"); Iterator<Carro> it = novaLista.iterator(); while (it.hasNext()) { Carro car = (Carro) it.next(); System.out.println("Nome: " + car.getNome()); System.out.println("Marca: " + car.getMarca()); System.out.println("Cor: " + car.getCor()); System.out.println("Valor: " + car.getValor()); System.out.println("=================================="); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } } /** * Cria e seta nosso objeto carro. Colocaremos esse objeto em uma lista. Tal lista, * contendo os objetos carro, irá ser serializada. */ public static List<Carro> preencherLista() { List<Carro> listaCarros = null; Carro carro1 = new Carro(); carro1.setCor("Preto"); carro1.setMarca("Ford"); carro1.setNome("F-250"); carro1.setValor(80000.50F); Carro carro2 = new Carro(); carro2.setCor("Prata"); carro2.setMarca("Chevrolet"); carro2.setNome("Celta"); carro2.setValor(26451.44F); Carro carro3 = new Carro(); carro3.setCor("Vermelho"); carro3.setMarca("Chevrolet"); carro3.setNome("Corsa"); carro3.setValor(38478.40F); Carro carro4 = new Carro(); carro4.setCor("Amarelo"); carro4.setMarca("Volkswagen"); carro4.setNome("Fusca"); carro4.setValor(2411.14F); listaCarros = new ArrayList<Carro>(); listaCarros.add(carro1); listaCarros.add(carro2); listaCarros.add(carro3); listaCarros.add(carro4); return listaCarros; } }
Feita a classe Main e verificado que não há nenhum erro de compilação, nós podemos executar nosso pequeno programa. Executando da forma que está postada aqui, a saída para console ficará assim:
Objetos salvos com Sucesso! Objetos Recuperados com sucesso Nome: F-250 Marca: Ford Cor: Preto Valor: 80000.5 ======================================= Nome: Celta Marca: Chevrolet Cor: Prata Valor: 26451.44 ======================================= Nome: Corsa Marca: Chevrolet Cor: Vermelho Valor: 38478.4 ======================================= Nome: Fusca Marca: Volkswagen Cor: Amarelo Valor: 2411.14 =======================================
E isso pessoal, espero que tenha sido útil o tutorial e que tenham gostado. Se quiserem saber mais sobre serialização de objetos utilizando o Java, você pode achar nesses links:
- http://en.wikipedia.org/wiki/Serialization#Java
- http://java.sun.com/developer/technicalArticles/Programming/serialization/
- http://www.deitel.com/articles/java_tutorials/20050923/IntroductionToObjectSerialization.html
Tocando arquivos MP3 com Java e JLayer
28/11/08
Uma das coisas que mais motivam nós programadores quando estamos aprendendo a programar ou que continuemos a estudar a linguagem a qual programamos é aprender sempre algo novo que a linguagem nos oferece. Claro que Java nos permite hoje fazer qualquer tipo de aplicação, porém o grande problema é que não sabemos como fazer o que queremos e a partir da aí buscamos cada vez mais o conhecimento que precisamos para fazer o que desejamos.
Recentemente descobri essa biblioteca chamada JLayer a qual nos permite tocar de forma muito fácil arquivos MP3 em nossos programas Java. Eu ainda não estudei essa biblioteca profundamente para ver tudo o que ela tem, porém hoje eu mostro como fazer o básico para tocar arquivos MP3 usando a Jlayer.
O tutorial é dividido em duas partes. A primeira parte (logo a seguir) ensina a tocar um arquivo mp3 em código Java de forma bem simples. Na segunda parte (que publicarei algum dia), ensinarei a tocar o arquivo mp3 usando threads e mostrando alguns outros recursos do JLayer.
Para fazer este tutorial, eu estou usando o seguinte ambiente de desenvolvimento:
- JDK 1.6
- JLayer 1.0.1
- Eclipse 3.4 (Ganymede)
- Ubuntu 8.10 (Intrepid Ibex)
A primeira coisa que devemos fazer é baixa a biblioteca JLayer. A biblioteca é grátis (LGPL) e você pode fazer o download dos binários e fontes aqui: http://www.javazoom.net/javalayer/javalayer.html
Depois de feito o download, descompacte o arquivo e copie o arquivo jl1.0.1.jar para a pasta lib de seu projeto. Copiado o jar, adicione a biblioteca ao classpath do projeto. Feito isso, vamos criar uma classe que será responsável por tocar nosso arquivo MP3. Eu chamei a classe de MP3 e ela ficou dessa forma:
package com.meupost.player; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import javazoom.jl.player.Player; public class MP3 { /** * Objeto para nosso arquivo MP3 a ser tocado */ private File mp3; /** * Objeto Player da biblioteca jLayer. Ele tocará o arquivo * MP3 */ private Player player; /** * Construtor que recebe o objeto File referenciando o arquivo * MP3 a ser tocado e atribui ao atributo MP3 da classe. * * @param mp3 */ public MP3(File mp3) { this.mp3 = mp3; } /** * Método que toca o MP3 */ public void play() { try { FileInputStream fis = new FileInputStream(mp3); BufferedInputStream bis = new BufferedInputStream(fis); this.player = new Player(bis); System.out.println("Tocando!"); this.player.play(); System.out.println("Terminado!"); } catch (Exception e) { System.out.println("Problema ao tocar " + mp3); e.printStackTrace(); } } }
A classe está comentada e explica o que significa os atributos e os métodos. No método play(), vemos que um objeto FileInputStream e BufferedInputStream são instanciados. O Player da biblioteca JLayer usa o BufferedInputStream para poder instanciar e deixar pronto o objeto Player, o qual nos permite enfim, tocar a música. O método play() do objeto Player é o responsável pela execução da música.
Note que como esse exemplo não é multithread, a música começará a tocar no momento da chamada do método play() e o fluxo de execução irá parar nesse método. O fluxo somente retornará quando a música terminar. Por fim, se ocorrer qualquer erro na execução da música, esteremos capturando a exceção e exibindo o stackTrace da mesma.
Terminada essa nossa classe MP3, vamos criar uma classe Main que instancia nossa classe MP3 e que permita nós testarmos a classe MP3 para ver se realmente funciona.
Eu criei uma classe Main assim:
package com.meupost.main; import java.io.File; import com.meupost.player.MP3; public class Main { public static void main(String[] args) { //String com o caminho do arquivo MP3 a ser tocado String path = "/home/ricardo/Músicas/Rock Clássico/Eagles - Hotel California.mp3"; //Instanciação de um objeto File com o arquivo MP3 File mp3File = new File(path); //Instanciação do Objeto MP3, a qual criamos a classe. MP3 musica = new MP3(mp3File); //Finalmente a chamada do método que toca a música musica.play(); } }
As quatro linhas de código nela estão comentadas e falam o que é cada comando. Acredito que você já possa testar e ver se funciona. Mande um Play aí.
Espero que tenham gostado. É bem simples, mas muito legal. No próximo tutorial mostrarei como fazer um tocador mais complexo utilizando threads.












Comentários