terça-feira, abril 24, 2007

Que suador! Primeiro contato com JSF My Faces

Dae galera, tudo tranqüilo?
Semana passada comprei o livro do Budi Kurniawan Programando em JavaServer Faces para aprender sobre o framework (que fora adotado pela empresa que eu trabalho em substituição ao WebWork).

Montando o ambiente de desenvolvimento na minha máquina em casa (dor de cabeça número 1):

- JDK 6 + Tomcar 6 + JSF implementado pela Sun

Nada funcionava! Não conseguia acessar a aplicação sem ter uma porrada de erros dos mais bizarros. Baixava os exemplos do livro, e outros, e nada de funcionar... cheguei a me desiludir um pouco, mas bola para frente a vida de “javeiro” não é mole não!

Baixei a implementação My Faces da Apache, troquei a porcaria do Tomcat 6 por uma versão 5.5 porque o Merve não reconhecia o Tomcat 6 como um Tomcar válido, e, bingo... consegui acessar a minha aplicação com dois links bem simples redirecionando o navegador através das regras de navegação e tudo mais.

Quase tudo perfeito, aí descobri que a maioria dos exemplos do livro (escrito em 2004) e de um outro que eu tenho aqui (Pro JSF and Ajax) não funcionavam porque eram baseados em implementações mais antigas do JSF! :(

Caraca, daí começa a briga da semana com as tags que formam a página, os métodos nos beans do exemplo e tudo mais...


Depois de muito peleiar por “essa internet sem fim” consegui resolver os problemas da minha página JSP :) e parti para o bean e a classe do meu exemplo (quem não conhece o livro é uma página com dois campos que se insere números e abaixo se tem um botão que os somam).

Bom somar os números, atribuir os campos da tela a um bean foi relativamente rápido. Ele (JSF) faz tudo para ti, só dizer que o campo é referente a um campo do bean e era isso! Até o funcionamento da página é fácil se você tem campos getters para todos os campos...

Mas porém, ah porém, sempre que eu entrava na página aparecia uma mensagem de erro dizendo:

Unable to find component 'firstNumber' (calling findComponent on component 'form:_idJsp1'). We'll try to return a guessed client-id anyways - this will be a problem if you put the referenced component into a different naming-container. If this is the case, you can always use the full client-id.

Bom o que ele queria me dizer, já ao carregar a minha página, era que a tag de label vinha após a tag que representava meu input. Bom dicas que encontrei na intenet:

a) colocar label APÓS input! Isso para quem já desenvolveu interfaces em xhtml soa estranho de mais!
b) colocar minhas tags de label e input dentro de uma outra tag, como panelGroup. Bem, foi o que eu fiz e começou a me dar erro dizendo que todo e qualquer conteúdo html eu deveria encapsular entre <f:verbatim></f:verbatim>... ahhh, mais trabalho po! Mas foi que eu fiz para não ter que optar pela opção a :P .

Depois deste trauma superado e da minha página funcionando com uma JSP e um bean parti para a segunda parte do exemplo que era usar ActionListener com ActionEvent. A moral da história era pegar o componente que disparou o evento, o elemento root da página e imprimir a estrutura que representava a árvore de componentes da página.

Dae começaram meus problemas novamente... mas depois de muito “googliar” e encher o saco do pessoal da lista de discussões do RSJUG, resolvi... e eram ridículos os erros:


a) meu commandButton estava chamando uma action e não actionListener como deveria;
b) depois eu não sabia como suprir a falta de alguns métodos que não existiam mais na implementação;
c) mais uma barberagem com um while (nossa que vergonha, mas era tarde, tava cançado ...:P );

Enfim... tomei um sarrafo!!! Uma surra. Mas está rolando!!! Uhú!
Agora pelo menos eu consegui fazer o primeiro exemplo do livro (putz) mas com direito a validações e tal... (muito fácil de fazer também).


Em resumo, meu exemplo da classe listener implementada em My Faces 1.1.5 para o exemplo do livro:

package estudo.jsf;

import java.util.Iterator;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseId;

public class SomarAction {

    public PhaseId getPhaseId() {
        return PhaseId.APPLY_REQUEST_VALUES;
    }

    public void montarArvore(UIComponent componente, int nivel) {

        for(int i = 0; i < nivel; i++) {
            System.out.print(" ");
        }

        System.out.println(componente.getId());

        Iterator children = componente.getChildren().iterator();

        while(children.hasNext()) {
            UIComponent child = (UIComponent) children.next();
            montarArvore(child, nivel + 1);
        }
    }

    public void processAction(ActionEvent event) {
        System.out.println("..... processando a acao\n");

        //--- descobre quem invocou essa ação
        UIComponent componente = event.getComponent ();
        System.out.println("..... objeto disparador da acao: " + componente.getId() + "\n");
        //---- fim

        //--- descobre quem é o elemento root
        FacesContext facesContext = FacesContext.getCurrentInstance();
        UIComponent componenteRaiz = facesContext.getViewRoot();
        System.out.println("..... objeto root: " + componenteRaiz.getId() + "\n");
        //---- fim

        //--- imprime a estrutura da árvore de componentes da tela
        System.out.println("-------------- arvore de componentes --------------");
        montarArvore(componenteRaiz, 0);
        System.out.println("---------------------
------------------------------");

        //--- fim
    }
}

Bom acabei de resolver os problemas e tal e to cançadão... juro que mais para frente tento explicar o exemplo. Quem quizer o código posta um comentário aí com seu e-mail que eu mando.

T+

quarta-feira, abril 18, 2007

Descontos no Submarino.com.br!

Ta ai uma coisa que eu não conhecia. Várias empresas (operadoras de telefonia móvel, empresas de cartões de crédito, etc...) oferecem aos seus clientes descontos nas compras entre faixas X de valores no site do Submarino.com.br. Onde eles divulgam isso eu não sei :P só descobri agora e não foi pela minha empresa de cartão de crédito :) foi pelo blog do amigo Tiago (que escreve sobre tudo menos Java no blog dele :) ).


http://www.submarino.com.br/univ
http://www.submarino.com.br/unibanco15/
http://www.submarino.com.br/credicardciti
http://www.submarino.com.br/credicarditau
http://www.submarino.com.br/maritimaseguros/
http://www.submarino.com.br/banespa/
http://www.submarino.com.br/real/
http://www.submarino.com.br/claro/
http://www.submarino.com.br/smiles/
http://www.submarino.com.br/speedy/
http://www.submarino.com.br/portoseguro/
http://www.submarino.com.br/citibank/
http://www.submarino.com.br/tva/
http://www.submarino.com.br/credicard/
http://www.submarino.com.br/catalogo/
http://www.submarino.com.br/bancoreal/
http://www.submarino.com.br/expm/
http://www.submarino.com.br/sudameris/
http://www.submarino.com.br/caixavisa/
http://www.submarino.com.br/sudameris0106/
http://www.submarino.com.br/unicard/
http://www.submarino.com.br/uol/
http://www.submarino.com.br/cartoesamex/
http://www.submarino.com.br/catalogo/
http://www.submarino.com.br/diners/
http://www.submarino.com.br/vivovantagens/
http://www.submarino.com.br/programaderelacionamento/
http://www.submarino.com.br/maesreal
http://www.submarino.com.br/hipercard07
http://www.submarino.com.br/amex2007
http://www.submarino.com.br/valedesconto
http://www.submarino.com.br/cartaoipiranga
http://www.submarino.com.br/gmcard


De repente agora eu compre aquele livro de UML e padrões que eu estão namorando a um tempinho :). Boas compas!

segunda-feira, abril 16, 2007

Mais um pouco de SQL BÁSICO!!!

Dae pessoal, tudo bele?
Hoje vi um post em uma lista de MySQL de alguém querendo saber como checar registros repetidos em uma tabela. Bom a solução mais simples, clara, NO GAMBI é o uso do HAVING (contendo).

E então criemos a tabela de testes (jogo rápido!):

CREATE TABLE DADOSREPETIDOS (ID INT, NOME VARCHAR(200));

Agora vamos popular (tá, minha criativida é f*** mesmo, não pensei em nada melhor do que meia dúzia de personagens de TV :D):

INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(1, 'John Due');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(2, 'Martha Kent');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(3, 'Nick Stokes');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(4, 'Scooby Doo');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(5, 'Bart Simpson');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(6, 'Clhoe Sullivan');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(7, 'Gil Grisson');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(8, 'Warrick Brown');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(9, 'Rachel Bilson');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(10, 'Clark Kent');
/* OS REPETIDOS */
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(11, 'John Due');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(12, 'Nick Stokes');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(13, 'Rachel Bilson');
INSERT INTO DADOSREPETIDOS (ID, NOME) VALUES(14, 'Bart Simpson');

E finalmente vamos selecionar os registros repetidos:

  SELECT COUNT(*), d1.Nome
    FROM JEAN.DADOSREPETIDOS d1
GROUP BY d1.Nome
  HAVING COUNT(*) > 1

Resultado da query:

+----------+---------------+
| COUNT(*) | Nome          |
+----------+---------------+
|        2 | Bart Simpson  |
|        2 | John Due      |
|        2 | Nick Stokes   |
|        2 | Rachel Bilson |
+----------+---------------+
4 rows in set (0.00 sec)



Beleza, essa é a maneira mais rápida de se procurar por registros iguais em uma tabela. Sendo que ele pega somente a primeira ocorrência, CUIDADO ao deletados se for fazer isso... as vezes, para não quebrar uma sequência por exemplo, é preferivel deletar os posteriores.

Espero ter ajudado.

Ajudem o blog aí pessoal prestigiando os nossos anunciantes :D.

sexta-feira, abril 13, 2007

Conteúdo XML formatado com XSL e JavaScript - CROSSBROWSER!

Dae pessoal.
Vou postar aqui uma maneira crossbrowser de renderizar conteúdo de arquivos XML formatados com XSL usando JavaScript.

Criando o arquivo contatos.xml:


<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="contatos.xsl"?>
<catalogo>
  <contato>
    <codigo>1</codigo>
    <nome>John Due</nome>
    <dddresidencial>51</dddresidencial>
    <foneresidencial>5555-6666</foneresidencial>
    <dddcomercial>51</dddcomercial>
    <fonecomercial>4444-5555</fonecomercial>
    <dddcelular>51</dddcelular>
    <fonecelular>8888-9999</fonecelular>
    <e_mail>jdue@jdue.net</e_mail>
  </contato>
  <contato>
    <codigo>2</codigo>
    <nome>Fulano de Tal</nome>
    <dddresidencial>51</dddresidencial>
    <foneresidencial>3333-4444</foneresidencial>
    <dddcomercial>51</dddcomercial>
    <fonecomercial>2222-3333</fonecomercial>
    <dddcelular>51</dddcelular>
    <fonecelular>9999-8888</fonecelular>
    <e_mail>fulano_tal@terra.com.br</e_mail>
  </contato>
  <contato>
    <codigo>3</codigo>
    <nome>Marta Kent</nome>
    <dddresidencial>51</dddresidencial>
    <foneresidencial>3333-2222</foneresidencial>
    <dddcomercial>51</dddcomercial>
    <fonecomercial>2222-1111</fonecomercial>
    <dddcelular>51</dddcelular>
    <fonecelular>8888-7777</fonecelular>
    <e_mail>martak@yahoo.com.br</e_mail>
  </contato>
</catalogo>


Criando o arquivo contatos.xsl:


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <html>
      <head>
        <style>
          * {
            font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
            color: #2988EA;
          }

          table.listResult {
            border-top: 1px solid #54A6FC;
            border-bottom: 1px solid #54A6FC;
            padding: 0px 0px 0px 0px;
          }

          tr.head {
            background-color: #CCE5FF;
          }

          tr.linhaImpar {
            background-color: #E3F1FF;
          }

          h2 {
            font-size: 10pt;
          }

          td, th {
            font-size: 8pt;

          }
        </style>
      </head>
      <body>
        <h2>Catálogo de Endereços</h2>
        <table border="0" cellpadding="7" cellspacing="0" class='listResult'>
          <tr class='head'>
            <th align="left">Cód.</th>
            <th align="left">Nome</th>
            <th align="left">Fone Residencial</th>
            <th align="left">Fone Comercial</th>
            <th align="left">Fone Celular</th>
            <th align="left">E-mail</th>
          </tr>
          <xsl:for-each select="catalogo/contato">
            <xsl:sort select="nome"/>
              <tr>
                <xsl:choose>
                 <xsl:when test="position() mod 2 = 0">
                    <xsl:attribute name="class">linhaPar</xsl:attribute>
                 </xsl:when>
                 <xsl:otherwise>
                    <xsl:attribute name="class">linhaImpar</xsl:attribute>
                 </xsl:otherwise>
                </xsl:choose>
                <td><xsl:value-of select="codigo" /></td>
                <td><xsl:value-of select="nome" /></td>
                <td>(<xsl:value-of select="dddresidencial" />) <xsl:value-of select="foneresidencial" /></td>
                <td>(<xsl:value-of select="dddcomercial" />) <xsl:value-of select="fonecomercial" /></td>
                <td>(<xsl:value-of select="dddcelular" />) <xsl:value-of select="fonecelular" /></td>
                <td><xsl:value-of select="e_mail" /></td>
              </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>


Criando o arquivo contatos.html:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt">
  <head>
    <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=ISO-8859-1"/>
    <meta http-equiv="pragma" content="no-cache"/>
    <meta name="author" content="Jean Jorge Michel"/>
    <meta name="robots" content="ALL"/>
    <meta name="revisit-after" content="4"/>
    <meta name="MSSmartTagsPreventParsing" content="true"/>
    <meta name="distribution" content="Global" />
    <meta name="rating" content="General"/>
    <meta name="language" content="pt-br"/>
    <meta name="description" content="Exemplo de uso de XML com XSL sendo aplicados em páginas HTML com JavaScript" />
    <meta name="keywords" content="xml, xsl, parser xml, crossbrowser, javascript"/>
    <title>.Jean J. Michel.</title>
  </head>
  <body id="conteudo">
    <script>
      var xml;
      var xsl;
      var processador;
      var xmlRetorno;
      var xslt;
      var conteudo;
      var localRetorno = document.getElementById('conteudo');

      if (window.ActiveXObject) { //Para IE

        xml = new ActiveXObject("Microsoft.XMLDOM");
        xml.async = false;
        xml.load("contatos.xml");

        xsl = new ActiveXObject("Microsoft.XMLDOM");
        xsl.async = false;
        xsl.load("contatos.xsl");

        document.write(xml.transformNode(xsl));
      }
      else if (document.implementation &&
               document.implementation.createDocument) { //Para FF, Mozilla, etc...

        processador = new XSLTProcessor();

        xls = new XMLHttpRequest();
        xls.open("POST", "contatos.xsl", false);
        xls.send(null);

        xslt = xls.responseXML;
        processador.importStylesheet(xslt);

        xml = new XMLHttpRequest();
        xml.open("POST", "contatos.xml", false);
        xml.send(null);

        xmlRetorno = xml.responseXML;

        conteudo = processador.transformToFragment(xmlRetorno, document);
        localRetorno.innerHTML = '';
        localRetorno.appendChild(conteudo);
      }
      else {
        alert("Browser desconhecido ou desatualizado!");
      }
    </script>
    <small>Acesse <a href="http://www.jeanjmichel.blogspot.com">jeanjmichel.blogspot.com</a> para mais exemplos.</small>
  </body>
</html>

O resultado:

Imagem do exemplo

Voce pode acessar o conteúdo aqui:

http://br.geocities.com/sadbuttruebr/blog/
scripts_posts/contatos.html


http://br.geocities.com/sadbuttruebr/blog/
scripts_posts/contatos.xml


http://br.geocities.com/sadbuttruebr/blog/
scripts_posts/contatos.xsl

quinta-feira, abril 12, 2007

Porque blogar porque não blogar... bloguei-o-o!

Porque blogar porque não blogar... bloguei-o-o!

Qual a intenção de se fazer um blog? O que postar? Onde divulgar?
Quando criei esse blog decidi que ia tentar ajudar pessoas que estavam na mesma agonia que eu estive quando tive que fazer certas coisas na minha vida profissional... sabe quando tu tem um abacaxi nas mãos e tem que descascá-lo e não a mínima noção de como fazer isso? Pois é.
Há quem julgue que não passar o conhecimento a frente é se proteger, resguardar e tal... discordo!
Até porque isso cria uma leva de gente desenvolvendo sem ter a mínima capacitação em certos aspectos. Tu pode imaginar uma pessoa desenvolvendo para WEB sem saber o que é HTML, JS ou até mesmo o que é um Servlet??? Eu posso! Então porque não passar a diante o (pouco) que sei?
Bom para isso o blog ta aí né... meio manco na verdade, porque não ando com tempo de despejar aqui muitas coisas que fiz até hoje e acho legal de se ter disponível como criação de procedimentos em Java para Oracle, até hoje só vi material em inglês na rede (alias não consigo conceber pessoas na área de TI que não tenham um bom domínio desta língua), e outras cositas más!!!
Bom, para variar estou fazendo mil coisas ao mesmo tempo :D (senão não era eu!), entre minhas atividades estão:

- Estudar JSF;
- Estudar analise de sistemas OO beeeeem a fundo (chega de só arranhar a superfície);
- Aprender um maldito framework proprietário de aplicações WEB que a empresa que eu trabalho está usando;
- Estudar para minha certificação (falta internacionalização e umas coisas assim... os apêndices do Java tutorial da Sun na verdade :P);
- Desenvolver o sistema da academia (ainda);
- Ensinar Java para um amigo que não sabe quase nada de desenvolvimento de softwares;

É... acho que é só isso... ahhh estou tentando manter o blog vivo :D (louvável!!!).

Então me ajudem, mandem aí sugestões de o que postar e tal... ficarei grato!

T+

Blog cadastrado no Rec6

quarta-feira, abril 11, 2007

Sem assunto...

Dae pessoal.
Hoje não tive tempo de ver nada para postar pois tive que tentar resolver um problema que o pessoal da empresa em que eu trabalhava está tendo com procedures do Oracle escritas em Java.

O problema é que a procedure executa um comando no sistema operacional e cria um "processo" que nunca é morto, o que devora a momória da máquina obrigando que o servidor seja resetado para liberar espaço.

Bom uma prévia da classe está aqui:

public class ComandoSO {

public static void executarComando(String coman
do) {

String[] linhaComando;

if (System.getProperty("os.name").toLowerC
ase().indexOf("windows") != -1) {
linhaComando = new String[4];

//Para XP e 2003, se for NT colocar
winnt
linhaComando[0] = "C:\\windows\\system32
\\cmd.exe";
linhaComando[1] = "/y";
linhaComando[2] = "/c";
linhaComando[3] = comando;
}
else {
linhaComando = new String[3];

linhaComando[0] = "/bin/sh";
linhaComando[1] = "-c";
linhaComando[2] = comando;
}

try {
Process pr = Runtime.getRuntime().exec(
linhaComando);
pr.destroy();
}
catch(Exception e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
executarComando("copy c:\\etiqueta.txt
lpt1");
}
}

Se alguém tiver uma dica para me dar COMENTE!!!

Até a próxima.

segunda-feira, abril 09, 2007

Exceções no Java

Dae pessoal, essa semana na empresa em que trabalho discutíamos sobre exceções em Java. Caramba, foi feia a peleia... cada um dizia uma coisa, usava o controle de exceções de uma maneira nas empresas por onde passaram (a equipe toda é de novos talentos vindos de grandes empresas do mercado de software bancário, fabricas de software , etc... com experiência em frameworks proprietários e comunitários diversos). Então resolvi postar esse material, não que eu estivesse certo na discussão ou os outros errados... mas para que sirva para mais alguém que um dia tenha tido dúvidas a respeito disto ou que desconheça o assunto. :D

Bom a definição de exceção (exception em inglês – palavra reservada no Java) pela Sun:

Uma exceção é um evento, que ocorre durante a execução de um programa, que interrompe o fluxo normal das instruções do programa.

Lindo isso. Nossa, estou contendo as lágrimas!
Quando ocorre um erro em um método em um programa desenvolvido em Java é criado um objeto (do tipo Exception) que contém as informações sobre o erro incluindo seu tipo e o estado do programa quando ocorreu o erro. Criar este objeto e passá-lo para a JVM chamasse lançar uma exceção (throwing an exception).
Depois que ocorre um erro e o objeto é criado o sistema tenta encontrar alguma coisa que trate este erro e este processo é chamado de pilha de chamada (call stack). Nada mais é do que uma lista de ordem inversa, ou seja, ocorre um erro vejo se o método o trata ou vou propagando este erro até que alguém o faça. Quem trata um erro? Os tratadores, ou apanhadores, de erros (exceptions handlers).

Imagine:

public double dividir(double dividendo,
double divisor) {
... faz e retorna o resultado da divisão
}

Se eu informar zero como divisor? FERROU! Claro que a linguagem Java retornaria um erro aqui, mas se isso não fosse tratado nosso programa pararia sem um tratamento a esta exceção.
A duas coisas a fazer com uma exceção, tratá-la ou propagá-la.
Vamos ver o primeiro, para isso temos que apanhar (catch) a exceção em um bloco tentar (try) apanhar (catch):

try {
... tenta alguma coisa
}
catch(Exception e) {
... deu erro, captura o erro e
o trata aqui
}

Ainda há a instrução por fim/finalmente (finally) que sempre é executado.

try {
... tenta alguma coisa
}
catch(Exception e) {
... deu erro, captura o erro e o trata aqui
}
finally {
... comandos que sempre devem ser executados
mesmo que haja uma execeção
}

Um exemplo de tratamento de exceções com uso do finally seria comandos a submetidos a bancos de dados que se houver um erro na transação, por exemplo, deveríamos fechar a conexão com o banco de dados para pouparmos recursos:

public void getSysdate() {
try {
... abre conexão, faz seleciona e retorna a
data do banco de dados
}
catch(SQLException e) {
System.out.println("Ocorreu um erro de
SQL: " + e);
}
catch(ClassNotFoundException e) {
System.out.println("Ocorreu um erro ao
tentar conectar ao
banco: " + e);
}
catch(Exception e) {
System.out.println("Ocorreu um erro que
eu não sei de que
tipo é: " + e);
}
finally{
... blablabla fecha a conexão, finaliza
objetos criados no processo
}
}

Beleza, mas aqui há pontos importantes a serem observados.

1. Eu estou tratando o erro no método, e não o propagando;
2. A "cascata" de tratamento das exceções vai da mais específica a mais genérica;
3. Poderia imprimir a mensagem de erro de outra maneira (mais abrangente) colocando um e.printStackTrace() no método catch.

Eu poderia não tratar minha exceção aqui dentro do método e sim propagá-la obrigando que qualquer classe que fizesse uso deste método tivesse que a tratá-la.

public void getSysdate() SQLException,
ClassNotFoundException,
Exception {
... faz o que eu queria fazer antes
}

Quando eu for chamar o método eu terei que o fazer dentro de um bloco try catch:

try {
instância_da_classe.getSysdate();
}
catch(SQLException e) {
System.out.println("Ocorreu um erro de
SQL:" + e);
}
catch(ClassNotFoundException e) {
System.out.println("Ocorreu um erro ao tentar
conectar ao banco: " + e);
}
catch(Exception e) {
System.out.println("Ocorreu um erro que eu
não sei de que tipo
é: " + e);
}
finally{
... blablabla fecha a conexão, finaliza
objetos criados no processo
}

Exceções é um capítulo bem complicado (nada de mais, só merece atenção) do Java e vai muito além desta minha explicação superficial sobre seu funcionamento. Sugiro que leiam o Java Tutorial e outros recursos que estão na internet para saber sobre os tipos de exceções que existem, sobre a classe Throwable e as suas filhas Error e Exception e as demais vantagens do uso de exceções no Java.

Para variar aqui tem dois links que deixam a disposição um exemplo de classe de exceção e uma classe que lança essa exceção. Divirtasse!

Saída obtida ao rodar o Calculadora:

shell> java Calculadora
No há divisão por zero.
at Calculadora.dividir(Calculadora.java:12)
at Calculadora.main(Calculadora.java:23)

http://geocities.yahoo.com.br/sadbuttruebr/blog/
exemplos_java/Calculadora.java

http://geocities.yahoo.com.br/sadbuttruebr/blog/
exemplos_java/DivisaoPorZeroException.java

terça-feira, abril 03, 2007

Genérics no Java (apartir do 5)

[update]
Pesso perdão a todos que leram o post antes deste update pois haviam 2 erros graves. O primeiro era a grafia da palavra generics como ressaltou um leitor nos comentários.
O segundo era que eu esqueci de trocar os sinais de < e > pelos seus respectivos códigos HTML numéricos.
Agora sim o post está funcionando :D e coloquei nos links abaixo os códigos usados para ilustrar os exemplos.
Desculpa aí pessoal, qualquer coisa comente aí!

http://geocities.yahoo.com.br/sadbuttruebr/blog/
exemplos_java/Caixa.java

http://geocities.yahoo.com.br/sadbuttruebr/blog/
exemplos_java/CaixaGenerica.java

[/update]


Dae pessoal, estamos aqui para mais um post de (in)utilidade pública e que já deve ter sido publicado em n sítios/blogs por aí na rede bem melhor redigido do que o meu :P, masss o meu é melhor! Hehehe ao menos eu e a minha mãe achamos... :P


Não sei como vivemos tanto tempo sem os tipos genéricos no Java. Que trabalho insano dava fazer certas coisas além de estarmos à mercê de erros bizarros. Vamos ilustrar a dor de cabeça com uma classe simples chamada Caixa.java que tem dois métodos: colocarNaCaixa e mostrarConteudo. O que a classe faz nada mais é do que criar uma caixa que recebe um objeto de qualquer tipo e mostra que tipo é o objeto colocado lá dentro e seu valor.

Vamos ao que é good, código!

public class Caixa {

private Object objeto;

public void colocarNaCaixa(Object objeto) {
this.objeto = objeto;
}

public Object mostrarConteudo() {
return objeto;
}

public static void main(String[] args) {
Caixa cxInteiros = new Caixa();

cxInteiros.colocarNaCaixa(10);

int i = (Integer)cxInteiros
.mostrarConteudo();

System.out.println("Tipo do objeto posto
na caixa: " + cxInteiros
.mostrarConteudo().getClass()
.getName());
System.out.println("Valor do objeto posto
na caixa: " + i);

Caixa cxStrings = new Caixa();

cxStrings.colocarNaCaixa("Olá genéricos");

String valor = (String)cxStrings
.mostrarConteudo();

System.out.println("Tipo do objeto posto
na caixa: " + cxStrings.mostrarConteudo()
.getClass().getName());
System.out.println("Valor do objeto posto
na caixa: " + valor);
}
}

Notem o seguinte, NADA impede de eu colocar qualquer tipo de conteúdo na minha caixa, a não ser uma convenção fraca explícita no código, algo como:
//Caixa só para inteiros
Caixa cx = new Caixa();

Patético... fora os inúmeros casts inúteis que temos:

Caixa cxInteiros = new Caixa();
cxInteiros.colocarNaCaixa(10);
int i = (Integer)cxInteiros.mostrarConteudo();

Bom como solucionar esse tipo de coisa?
Resposta: GENERICS!

O que é um objeto/método genérico?
É uma classe/método que só aceita um certo tipo de parâmetro... ta deixemos de blablabla e vamos ao código disto tudo:

public class CaixaGenerica<T> { //Ai já diremos que
//tipo de dado
//esperar.

private T objeto; //T é do mesmo tipo do T que
//especificamos quando instan-
//ciamos o objeto.

public void colocarNaCaixa(T objeto) {
this.objeto = objeto;
}

public T mostrarConteudo() {
return objeto;
}

public static void main(String[] args) {
//Instanciamos uma caixa só para inteiros
CaixaGenerica<Integer> cxInteiros =
new CaixaGenerica<Integer>();

cxInteiros.colocarNaCaixa(10);

/*
* O melhor, sem CAST! O compilador sabe que
* tipo de dados tem na caixa.
*/
int i = cxInteiros.mostrarConteudo();

System.out.println("Tipo do objeto posto na
caixa: " + cxInteiros.mostrarConteudo().getClass()
.getName()
);
System.out.println("Valor do objeto posto
na caixa: " + i);

CaixaGenerica<String> cxPalavras =
new CaixaGenerica<String>();

cxPalavras.colocarNaCaixa("Java Generics é
o bixo!");

String palavra = cxPalavras.mostrarConteudo();

System.out.println("Tipo do objeto posto
na caixa: " + cxPalavras.mostrarConteudo().getClass()
.getName());
System.out.println("Valor do objeto posto
na caixa: " + palavra );
}
}

Não tem como instanciarmos uma caixa de um gênero e tentarmos atribuir um valor de outro a caixa... dará erro ao tentarmos compilar a classe.

Agora pense em todo tipo de coleção que você já usou antes dos generics que agora lhe
poupariam algum tempo sem casts e sem erros...

Isso é post de coisa antigaaaaaa, só para encher lingüiça mesmo, mas me espanta gente que se diz desenvolvedor Java e não conhece generics.

Até a próxima e já sabe né... comenta aí!

Injeção de dependências com Spring Framework

Dae pessoal.

Semana passada participei de um treinamento de 8h sobre o Spring.

Pra quem não sabe Spring é um frame work de injeção de dependências.

Para que serve, quando usar, se funciona... não me pergunte :P veja você mesmo e teste sobre suas necessidades.

O que eu posso dizer sobre o pouquíssimo que sei até agora é que é bem legal o negócio além de o Spring ter também uma parte que cuida do MVC da aplicação (mas não é necessário usá-lo, você pode desenvolver usando Struts, WebWork, JSF e usá-lo onde for cabível).

Bom, só pra dar um exemplo de uso (útil barbaridade!!! :P):

Uma classe normal:


package estudo.springframework;

public class BeanNormal {

private String mensagem = "Essa é a mensagem padrão.";

public String getMensagem() {
return mensagem;
}

public void setMensagem(String mensagem) {
this.mensagem = mensagem;
}

public BeanNormal(String mensagem) {
super();
this.mensagem = mensagem;
}

public BeanNormal() {
super();
}
}

public class InjetaDependencia {
public static void main (String[] args) {

BeanNormal b0 = new BeanNormal();
System.out.println(b0.getMensagem());

}
}

Bem, agora com o uso do Spring vamos mudar o valor do atributo mensagem injetando um valor em usar o método setMensagem(Srtrin mensagem) da classe:

package estudo.springframework;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class InjetaDependencia {
public static void main (String[] args) {

BeanNormal b0 = new BeanNormal();
System.out.println(b0.getMensagem());

final BeanFactory bf = new XmlBeanFactory(
new ClassPathResource("/beannormal.xml"));
final BeanNormal b1 =
(BeanNormal) bf.getBean("beannormal");

System.out.println(b1.getMensagem());

}
}

A saída no primeiro caso seria:
Essa é a mensagem padrão.

Depois que usamos o Spring o que ele faz é injetar alguma coisa em tempo de execução em algum lugar, nossa que definição profunda!

A saída depois que mudamos o código será:

Essa é a mensagem padrão.
Valor injetado pelo Spring ;-)

Bom não me peçam mais do que isso, porque o curso que fiz não passou disto :P e foi muito blablabla pra pouca ação para o meu (humilde) gosto que gosto de aprender com a mão na massa e não vendo slides e tal... mas daqui a uns dias eu posto algo que preste pois vou usá-lo com certeza no meu projeto junto com Hibernate e JSF.

Quem quizer baixar os fontes:

http://geocities.yahoo.com.br/sadbuttruebr/blog/
exemplos_java/BeanNormal.java

http://geocities.yahoo.com.br/sadbuttruebr/blog/
exemplos_java/InjetaDependencia.java

http://br.geocities.com/sadbuttruebr/blog/
exemplos_java/beannormal.xml


Até a próxima e comentem aí!

IDE para usar com o MySQL, SQL Server, Access e Oracle :P


Esta semana estava procurando uma interface gráfica para
trabalhar com o MySQL. A muito tempo atrás eu usava uma da
própria MySQL AB, mas ela pecava em vários aspectos.
Então em uma busca rápida pela internet descobri que a mais
nova versão do Oracle SQL Developer, que eu já usava para
bases Oracle, tem suporte a conexões com o MySQL, SQL Server
e o Access. Além de ser uma ferramenta totalmente desenvol-
vida em Java e blablablabla e de graça!

Estou usando a ferramenta a poucos dias mas já estou encan-
tado. Muito boa mesmo, recomendo para usar com o MySQL.



Essa é a tela principal da ferramenta: Aqui do lado esquerdo
tem as conexões criadas e configuradas, quando se expande
a árvore pode se ver as bases, tabelas, funções, gatilhos,
etc... Inclusive quando se seleciona uma tabela de imediato
aparece seus campos na tela.

Podesse navegar para a aba data e ver todos os registros
da tabala, selecionar uma função por exemplo e ver seu código
fonte, etc...







Agora para criar uma conexão com o MySQL você precisa ter o
JDBC (o drive para conexão a bancos de dados usado por
aplicativos Java) que pode ser baixado no site da MySQL AB
com o nome de connector J.

Para registrar esse drive no SQL Developer vá em
tool\preferences... e vá na opção Third Party JDBC Drives.
Aponte para o arquivo .jar (por exemplo,
mysql-connector-java-5.0.4-bin.jar). Agora é só criar uma
conexão como nos passos abaixo:



1) Vá em File\New
2) Escolha Database Connection



3) Na tela de configuração:
a) Informe um nome para a sua conexão, no meu caso Conexão
de Teste;
b) Informe o usuário e senha que irá conectar, pode ser
root;
c) Nas abas abaixo escolha MySQL;
d) Hostname e Port devem vir preenchidos com o padrão da
sua máquina, algo como localhost e 3306;
e) Clique em Choose Database para carregar na lista ao
lado o nome das bases de dados que você tem criadas;
PS: Se aparecerem as as bases na lista a conexão está
ok, o drive está funcionando.
f) Para testar a conexão você pode clicar no botão Test e
checar a mensagem ao lado:



Agora na arvore a esquerda aparecerá sua conexão, expan-
dindo-a você verá todos os objetos dela e pode submeter
comandos SQL como no exemplo abaixo (para executar o comando
precione F9 ou clique na seta verde acima do prompt):





Té mais pessoal, e em breve vou postar uns exemplos de
Java, pois o sistema que mencionei que faria para uma
academia e tal será em Java :D .