Mostrando postagens com marcador Wicket. Mostrar todas as postagens
Mostrando postagens com marcador Wicket. Mostrar todas as postagens

18 Agosto 2008

Como criar um projeto Wicket


O Fábio comentou no meu post uma dúvida sobre como criar um projeto Wicket no Eclipse e me senti na obrigação de compartilhar aqui com vocês, a mesma instrução que passei na palestra do RioJUG.

O Apache Wicket possui um archetype de QuickStart para o Maven, muito útil para iniciar um projeto. Este post não é um tutorial do Apache Maven, mas seguindo estes passos, você possuirá um projeto funcional em questão de segundos (dependendo da velocidade da sua Internet).

Acessando o site Apache Wicket - QuickStart, você verá um formulário para configurar o projeto. Preencha com algumas informações óbvias, como o pacote e o nome do projeto, em minúsculo, e selecione qual versão do Wicket você quer utilizar. Na caixa abaixo, aparecerá o comando para ser executado no seu terminal/console.

Isto irá criar uma estrutura padronizada de diretórios para um projeto Web do Maven. Após o término, execute o seguinte comando para verificar se o projeto está OK.

$ mvn jetty:run

Isto irá executar o Jetty (Servlet Container) Plugin e colocará no ar o projeto criado, no endereço http://localhost:8080/.

Agora, para ter o projeto configurado corretamente no Eclipse, basta também utilizar outro plugin para o Maven, chamado Eclipse Plugin. Execute o seguinte comando na pasta do projeto:

$ mvn eclipse:eclipse -DdownloadSources=true

Você deve configurar o Workspace do Eclipse para ter uma Classpath Variable apontando para o repositório do Maven. Também é possível acrescentar uma propriedade na hora de executar este plugin, para configurar o projeto como um Dynamic Web Project, do WTP. Para maiores informações, veja a documentação do Eclipse Plugin.

É isso. Eclipse e Apache Maven, é tudo o que você precisa para criar um projeto.

[]'s!

Link para este post

31 Julho 2008

Palestra sobre Wicket no RioJUG


Aos curiosos, interessados e àqueles (loucos) que preferem assistir a uma palestra do que ir para um Happy Hour de botequim. Apresentarei uma prévia da minha (possível) palestra submetida ao JustJava 2008, no RioJUG (que fica... no Rio? :-D).

A Palestra:

    Apache Wicket é uma maneira natural de desenvolver sistemas para a plataforma web com produtividade.

    Desenvolver aplicações cujos modelos HTML não tenham tags nem scripts proprietários; usar pura orientação a objeto nos componentes e inclusive nas páginas; suporte nativo e extensivo a validações e conversões. Integração com Spring, Ajax de fábrica, testabilidade, segurança, suporte a POJO em sua concepção, sem arquivos de configuração, suporte ao botão de voltar e duplo-clique, reusabilidade através de componentização.

    Será mostrado por que Apache Wicket é produtivo, simples, rápido e divertido; principais funcionalidades e uma demonstração com código fonte.

Segue informações:

Dia: 06/agosto/2008 (quarta-feira)
Horário: 19:00 horas
Duração: 2 horas
Local: Auditório do SENAC CIT - Rua Santa Luzia, 735 - 7o. andar, Centro
Dica de Acesso: Estação Cinelândia do Metrô pela saída Santa Luzia, atrás do Consulado Americano.


Conto com a presença de todos! (mesmo que você more longe, não deixe de vir.)

[]'s!

Link para este post

29 Julho 2008

Wicket in Action: Revisão do Livro

Hoje recebi um e-mail um tanto quanto inusitado. O diretor de Marketing da editora Manning me disse que Eelco e Martijn pediram para que eu, juntamente com outros entusiastas do framework Apache Wicket, recebessem uma cópia eletrônica do livro Wicket in Action para avaliar, revisar e opinar a respeito. Em troca? A chance de ter a minha opinião na contra-capa do livro.

Também terei a responsabilidade de num prazo não muito longo, publicar aqui para vocês, uma revisão detalhada sobre o livro, tanto em inglês como em português.

Fiquem de olho!

"Apache Wicket - porque Java para Web pode ser simples."

[]'s !

Link para este post

30 Junho 2008

Cache do Wicket em Cluster: entenda o processo


Muita gente quando descobre que o Wicket guarda tudo na sessão do usuário, rapidamente lança duas perguntas de grande peso:

  1. Guardar tudo no HttpSession não estourará a memória do servidor?
  2. Não ficará lenta a replicação destes objetos entre os nodes de um Cluster?
Para começar, é verdade sim, que o Wicket guarda tudo... tudo... na sessão do usuário. O objeto HttpSession é alimentado a cada click do usuário com as instâncias das páginas (e toooodas as suas versões anteriores - Suporte Backbutton), assim como os dados destas páginas, de formulários, estados de componentes (visível, escondido, selecionado, etc) e tantas outras informações forem necessárias. Mas, não se preocupe. Assim como o Garbage Collector se encarrega de cuidar da memória da VM, o Wicket (>= 1.3) se encarrega de cuidar da sua "memória". Para isso, existe o DiskPageStore.

Antes de continuar, explicarei agora os motivos que levam o Wicket a funcionar desta forma (enxer a memória). Se você já sabe, então pule dois parágrafos. :-)

O Wicket armazena na HttpSession as instâncias da página primeiramente para que quando você, desenvolvedor, construir uma página ou um componente, sinta-se num ambiente verdadeiramente Orientado a Objetos. Diferentemente dos frameworks action-based, aqui é possível manter referências de objetos, variáveis locais e de instância, declaradas sem qualquer problema pois quando o usuário clicar, o objeto que receberá o evento, é o mesmo que foi criado no início. Ótimo não? Sem dúvida! Não precisa-se saber de "parâmetro do request" ou qualquer outra tranqueira Web. É Swing-like, Java puro, POJOs e até parece desktop de verdade.

Pois bem, com os objetos na HttpSession, foi possível implementar algo ainda mais bacana: suporte ao backbutton do browser. Cada vez que o usuário submete alguma coisa a um componente, o estado deste componente é guardado na Session, como uma versão. É como se fosse feito um snapshot. Se o usuário clicar em voltar, e submeter alguma coisa novamente, o Wicket tem como saber que alguma coisa ali está diferente e poderá evitar problemas como submissão duplicada de registro, ou atualização indevida de dados já existentes. Maravilha!

E então você pensa: "que ótimo, Wicket me dá várias funcionalidades a troco de uma sessão de 15Megabytes por usuário". É verdade que se não houver um cuidado, a sessão pode explodir sim. Aqui vão algumas regras então para minimizar os riscos de uma HttpSession Shrek: Como funciona o SecondLevelCacheSessionStore?
Agora, a parte que nos interessa: Wicket's Garbage Collector!

O "lixo" que o Wicket precisa remover é basicamente, versões antigas das páginas/componentes criados pela navegação do usuário no site. É possível, mas pouco provável, que o usuário clique num Voltar e tente fazer algo. Por isso o framework elimina versões muito antigas (o padrão é manter somente as últimas 5 em deployment mode). Mas e se o desenvolvedor quiser armazenar mais versões, sem comprometer a memória do servidor, e conseqüentemente proteger sua aplicação de ataques Denial of Service? Para isso serve o SecondLevelCacheSessionStore.

Sua utilização depende do arquiteto do sistema em definir no Application do Wicket, que o framework deve utilizá-lo. Porém, antes de apresentar o código, vamos entender como os objetos são persistidos. A persistência é feita por algum objeto que implementa a interface IPageStore. Este objeto será responsável por persistir - storePage() - seja em banco de dados, arquivo flat ou qualquer outro meio, os objetos que o framework considerar não mais necessários na sessão, ou quando o usuário precisa ver algum dado mantido em versão anterior de algum componente - getPage().

A implementação padrão para a interface IPageStore, é a classe DiskPageStore. Nela, ocorre o processo de serializar as páginas e toda a árvore de objetos ali contida, para posteriormente salvar no disco do servidor. Problema de memória gigante resolvido! Mas... pera. Você possui um cluster? Hmm... Será que o Wicket vai funcionar sem problemas ali? Se ele arquivar as páginas no disco de um servidor, o que acontecerá em outro nó do cluster?!

Wicket em ambiente Clusterizado
A grande sacada...

Serialização é um processo complicado e lento. Não falei antes, mas é importante lembrar que todos os objetos que ficarem na HttpSession, devem implementar Serializable. Isto é importantíssimo; se houver um não serializável, o Wicket vai gritar no log. Agora, se tudo correr bem, os objetos serão serializados e persistidos no disco pelo objeto DiskPageStore, estando o aplicativo Wicket em cluster ou não.

Num ambiente Cluster regular - que segue os padrões das configurações simples e funcionais (ex: Tomcat em Cluster) - o framework inteligentemente coloca as páginas já serializadas no processo de replicação, para que quando o objeto HttpSession chegar no outro nó, não há perda de processamento em realizar a tarefa de serialização duas vezes. As páginas também não são de-serializadas; vão direto para o DiskPageStore que as armazena para uso futuro, se necessário. Este mecanismo é o que garante a performance do framework neste tipo de deploy.

Espero poder ter desmistificado agora a idéia de que Wicket estoura com a memória dos servidores, nem tão pouco que não suporta ambientes clusterizados.

Hands-On: Configurar a aplicação para utilizar SecondLevelCacheSessionStore
Mão na massa...

Para encerrar, veja como é simples configurar o SecondLevelCache com o DiskPageStore:
public class MyApp extends WebApplication {
@Override
protected ISessionStore newSessionStore() {
return new SecondLevelCacheSessionStore(this, new DiskPageStore());
}
}
E agora, que tal? É fácil ou não é?! :-D

PS: o Anjo Negro ataca novamente... desta vez, com gol de letra!

[]'s!

Link para este post

25 Junho 2008

URLs simples no Wicket e o novo Eclipse

Uma das coisas bacanas no Wicket é a possibilidade (extremamente simples) de definir URLs RESTful, ou apenas "URLs simples" para as páginas do sistema.

No artigo Wicket Creating RESTful URLs é possível ver como o framework provê de forma bem objetiva, na API, esta funcionalidade. Mas, resumindo: se você quer definir URLs mais amigáveis, diferentemente dos padrões do framework, que são mais ou menos assim:

http://www.example.com/wui/?wicket:bookmarkablePage=%3Anl.stuq.demo.SomePage
É possível deixá-las assim:
  • http://example.com/users/
  • http://example.com/users/{user}
A facilidade de desenvolver, em puro Java, com este framework é o que faz a diferença dentre tantos frameworks Web. O padrão ZeXCo, ou apenas... Zero-XML-Configuration, mais uma vez mostra-se eficáz.
  public WicketApplication() {
Class pageClass = ProductDetailPage.class;
String[] params = new String[]{"id"};
MixedParamUrlCodingStrategy productURLS = new MixedParamUrlCodingStrategy("products", pageClass, params);
mount(productURLS);
...
Isto é o suficiente para acessar a página desta forma: http://example.com/products/23. Onde: "products" indica a página e "23" é o id passado via parâmetro para a classe. Agora, como interceptar este parâmetro? No construtor da página é preciso receber o objeto PageParameters:
  public ProductDetailPage(PageParameters params) {
String id = params.getString("id");
Product product = productService.loadById(id);
setModel(new CompoundPropertyModel(product));
...
}
Pronto! Agora as URLs estão beeeeem bonitinhas... :-P


E para terminar o post, recebi o e-mail agora sobre o anúncio do lançamento do Eclipse Ganymede (nome meio ... gay, não? - mas para os curiosos, Ganymede é uma lua de Júpiter). O pacote oferece um release único e integrado de 23 projetos da Eclipse Foundation.

Há também um concurso para os melhores blogs que postarem sobre o Ganymede; não adianta ser apenas um comentário; o que eles querem mesmo são reviews bem detalhadas... eu to fora! Mas se você quiser participar, acesse a página Ganymede Around The World.

É isso. Agora, é fazer o download do Eclipse Ganymede, do Apache Wicket 1.4m2 e desenvolver aplicações Web com maior produtividade, qualidade e diversão! :D

[]'s

Link para este post

04 Junho 2008

Java Generics chateia desenvolvedores: muito código!


Aos que acompanham o framework web Apache Wicket, devem ter notado que o branch 1.4 progrediu para ser compatível somente com Java 5 e superior. Isto significa uma evolução, não apenas na minha opinião mas na de muitos outros usuários da Wicket User List e é claro a dos committers. Deste modo, novos métodos, classes e sintaxes podem ser utilizadas pelo framework, reduzindo seu código no Core e facilitando o seu uso. Até a versão 1.3.x, o framework era dividido entre módulos com suporte até Java 1.4, e outros somente para Java 5 e superiores, como o Wicket Spring Annotations. Hoje, todos os módulos que eram separados desta forma, foram unidos e hoje temos somente, por exemplo, Wicket Spring (já com as anotações lá dentro.) Veja as novidades aqui.

Fora as novidades comuns do Java 5, praticamente todo o framework foi generalizado, pois devido a duas classes importantes, a Component e a IModel, serem diretamente relacionadas e sendo esta última, a que provê os dados para a Component, o uso de Generics foi aplicado, tornando estas como: IModel<T> e Component<T>. Isto implicou em mudanças em diversas partes do código é lógico. Métodos como:


  • T IModel.getObject();
  • T Component.getModelObject();
  • Model<T> Component.getModel();
introduziram o conceito de Generics de forma elegante, pois agora o tipo do objeto contido no IModel, e consequentemente no Component, era conhecido - type-safe. Porém, após muitos migrarem seus aplicativos para a nova versão, começou-se uma longa discussão a respeito das reais vantagens do uso do Java Generics. Muita gente começou a reclamar da quantidade de vezes que era necessário declarar o tipo, como no exemplo abaixo:

TextField<String> txtNome = new TextField<String>("nome", new PropertyModel<String>(usuario, "primeiroNome"));

Tudo isso para ter estas facilidades:

String nome = txtNome.getModelObject(); // type safe cast
String nome2 = txt.getModel().getObject(); // type safe cast

Generics começou então a torrar a paciência de muita gente que até então, adorava o framework pela sua simplicidade e modelo Java puro que nos levava até a obter uma certa diversão na codificação. Conclusão: Generics deixou o framework chato de codificar. Ter que indicar 3 vezes que o component vai mostrar uma String, é insano.

A discussão começou na Wicket Dev List no dia 07 de Março deste ano, pelo Eelco que questionou justamente o que coloquei de exemplo aqui, como vocês podem ler aqui. Sua preocupação não foi em vão, entretanto. Outras discussões nasceram sobre diversos outros casos onde a redundância de tipagem chateava o desenvolvedor. O assunto tomou proporções absurdas quando decidiram questionar os usuários do framework na User List. A discussão iniciada em 01 de Junho pelo próprio Eelco, entitulada "users, please give us your opinion: what is your take on generics with Wicket" já consta com mais de 180 respostas de todos os tipos: usuários chateados, contentes, com sugestões ou desaprovações totais ao uso de Generics.

No dia 2 de Junho, Jonathan Locke postou em seu blog o artigo "Wicket and generics and the end of Java" que causou uma repercusão absurda no The Server Side, com mais de 100 respostas, até algumas calorosas, sobre o uso ou mau uso de Generics.

Hoje, não se tem ainda a conclusão do quê a galera do Wicket vai fazer a respeito de Generics no Core, mas se lermos as discussões citadas acima, fica claro o descontentamento dos desenvolvedores Java com a verbosidade absurda que Generics introduziu no código. A última que lí é que pelo menos no Java 7, isto já será possível:

Bar<Foo> bar = new Bar(fooObject);
Foo foo = bar.getObject();

Se resolve todos os problemas? Definitivamente não. Ainda tem muita coisa para ser discutida. Talvez no Java 9 fica pronto! :-)

[]'s!

Link para este post

19 Dezembro 2007

Whiteboard dos frameworks Web

Neste post do Enter The Jboss Matrix, o autor Shaun Connolly apresenta o resultado de um whiteboard poll, sobre o uso de Application Servers e Web Frameworks. O resultado apresenta forte liderança pelo JBoss e JSF.


Vou falar aqui sobre os resultados da votação de Web Frameworks. Vendo este whiteboard, levanto algumas questões:

  • Porque JSF é lider?
  • Porque tem gente que ainda utiliza Struts e Struts 2?
  • Quem são os malucos que utilizam Spring MVC?
  • Que tipo de desenvolvedores utilizam Tapestry?
  • Porque em tão pouco tempo, o uso do Wicket cresceu a ponto de ultrapassar Tapestry, Grails e Rails?
Perguntas pertinentes, que me arrisco a dar algumas respostas neste post que, sem dúvida será bem controverso. :)

Porque JSF é lider?
Para mim, o principal motivo é simples: JSF é uma especificação definida pelo JCP. Isto favorece a adoção por grandes empresas e projetos que preferem algo padronizado e que possui uma grande oferta de cursos, livros e produtos.

Mas me questiono: o JavaServer Faces puro (Reference Implementation) não tem nada demais. A produtividade com ele é baixa, o suporte das IDEs só é bom quando amarrado a componentes de terceiros e como comentei num post anterior, usa-se muito SOP (String Oriented Programing.) A solução para torná-lo verdadeiramente produtivo é sempre abraçar algum framework JSF mais robusto (leia-se: mais componentes e uma arquitetura engessada), como o JBoss Seam, Oracle ADF Faces ou o da Sun (experimente o NetBeans 6 e notará que vários componentes são específicos da Sun... não sei exatamente de onde vem, qual o projeto, mas sei que tem.)

Abraçar um produto JSF implica em se amarrar a este produto e seus componentes customizados, não podendo mudar de Vendor assim como é prometido pela especificação e tantos desenvolvedores, gerentes e arquitetos ainda, sendo enganados pelo marketing, acreditam.

Sei, e concordo, que há espaço para o JavaServer Faces, mas vamos parar com o euforismo de que JSF é produtivo, padronizado e livre de implementação, ok? Ninguem mais vai trabalhar com JSF RI. A solução será sempre escolher entre uma especialização ou outra (Seam, ADF, etc ...) para tornar essa máxima verdadeira.

Porque tem gente que ainda utiliza Struts e Struts 2?
Desenvolvi em Struts 1.x durante boa parte da minha carreira, e assim como postei da outra vez, acredito que foi-se o seu tempo. Entramos numa era de programação baseada em componentes, e não actions. Reutilização de código na composição de paginas agrupando componentes: este sim é o modelo de hoje (visto no JSF, no Tapestry, Wicket e alguns outros).

Então porque tem gente que ainda utiliza Struts e Struts 2? O primeiro é simples: manutenção. Tem muito sistema que foi feito em Struts e por falta de tempo ($$) não existe o interesse em migrar para outro framework (nem que fosse o Struts 2). O segundo fica difícil de dizer exatamente o porque, mas me arrisco a dizer que é pelo simples fato de ser a junção de duas fortes comunidades (Struts e WebWork) que são devotos do modelo Action-based. Esta comunidade está presa a um modelo de construção Web, onde se sintam confortáveis e confiantes na hora de construir suas telas. Eu entendo. Já me senti assim um dia... :) Mas só por um dia.

Acho que o número de projetos em Struts e Struts 2 diminuirá com o tempo. Minha previsão é que, assim que JSF 2.0 sair oficialmente, teremos uma queda drástica na adoção de Struts 2 como framework web para novos projetos. Deste modo, dois frameworks irmãos irão se encontrar no limbo da manutenção.


Quem são os malucos que utilizam Spring MVC?

Alguém ae utiliza Spring MVC? Por favor, comenta aqui quais os motivos que o levaram a adotá-lo! Porque eu não faço a menor idéia. Na minha opinião, é apenas um Action-based amarrado ao Spring. O que ele tem que outros frameworks neste modelo não oferecem?

Deixo a resposta desta pergunta para os comentários... :)

Que tipo de desenvolvedores utilizam Tapestry?
O tipo que quer correr riscos e gosta de seguir um Pastor. O risco de sair uma versão nova com mudanças tão grandes na API que o forçam a duas únicas opções: ficar largado na versão anterior ou migrar para a última. Se você não sabe, o Tapestry é escrito praticamente, por um único desenvolvedor chamado Howard Lewis Ship. Isso implica que, se o cara decidir (como já fez entre as versões T3, T4 e T5) ter idéias novas e implementá-las, ele o fará sem dó nem piedade da comunidade que utiliza o framework.

Minha sugestão: fique longe de frameworks sem compromisso com seus usuários.

Porque em tão pouco tempo, o uso do Wicket cresceu a ponto de ultrapassar Tapestry, Grails e Rails?
Foi uma surpresa para muitos, quando o framework foi incorporado pela Apache rapidamente. O processo na incubadora foi rápido, o que demonstra a maturidade e o compromisso dos desenvolvedores. Além disso, é notável ver que este compromisso é diário visto o número de dúvidas respondidas (muitas até instantâneas via IRC) pelos commiters e usuários avançados.

Não há como negar que a comunidade Wicket já está consolidada, ao ponto de ultrapassar a do Tapestry e Grails. Mas não basta ter comunidade (voltemos ao exemplo do Struts), é preciso mais que isso. Aos que já colocaram seus dedos em algum exemplo de Wicket, viram o quanto é produtivo e rápido a construção de telas e componentes genéricos. Mas ainda, não é isso que atrai novos adeptos ao framework. É divertido desenvolver com Wicket.

Foi-se o tempo de apanhar para XMLs e Strings escritas por engano. Ou de taglibs monstruosas cheias de parâmetros. O conceito de POJO + POH é o que faz a diferença em relação aos outros frameworks. Some isso a uma API bem moldada a ponto de ser comparada com a do Swing, e você terá uma facilidade incrível para entender os métodos e classes do framework.

Para 2008, o plano é apresentar ainda mais a capacidade do Wicket a vocês que frequentam este blog. Não que eu queira iniciar uma religião com isso, mas apenas mostrar que existem alternativas mais produtivas. :)

[]'s
miojo

Link para este post

17 Dezembro 2007

Slides do Wicket

Eu sabia que haveria uma palestra no Javapolis deste ano sobre o Wicket, então fui atrás e caí de paraquedas no site SlideShare. O legal é que, não apenas encontrei os slides da palestra Wicket in Action, apresentada pelo Martijn Dashorst (um dos Core Commiters.) Aproveitei também para fazer o upload da minha palestra deste ano e incrementar ainda mais a quantidade de slides sobre o framework!

Com pressa em ver a palestra que o Martijn deu no Javapolis? Confere logo abaixo:



[]'s!

Link para este post

23 Outubro 2007

Filosofia do Wicket

Eelco Hillenius, um dos Core Commiters do framework web Wicket, em um de seus insights sobre desenvolvimento Web:

"Imagine being told that you can use Java as your programming language, but at the same time being told not to create your own classes. [...]
I fail to understand why that has to be different for UI development, and Wicket proves it doesn't have to be so."
Em português:
"Imagine ouvir que você pode usar Java como linguagem de programação, mas ao mesmo tempo ouvir para não criar suas próprias classes. [...]
Não consigo entender porque precisa ser diferente para o desenvolvimento de UIs, e Wicket prova que não precisa ser."
Artigo completo

[]'s!!
miojo

Link para este post

13 Outubro 2007

Combos com Ajax no Wicket

Fiquei com medo quando tive que alterar uma tela para que ela não fizesse refresh, pra atualizar os dados de uma combo quando uma anterior tinha sua seleção alterada. Qual foi minha surpresa, quando... o código do método refresh era, na verdade, maior que o código
que utiliza o método Ajax?!?! Sensacional!!

HTML

<select id="estados">
<option>Bar</option>
</select>

<select id="cidades">
<option>Foo</option>
</select>

Java
Map cidades = listCidades(); // Mapa de cidades para RJ, SC e SP
List estados = Arrays.asList(new String[]{"RJ", "SC", "SP"});
DropDownChoice ddCidades = new DropDownChoice("cidades", Collections.EMPTY_LIST);

Quem deve receber notificações de seleção para atualizar a combo ddCidades, é a combo ddEstados, criada logo abaixo. Veja o comparativo, entre o código que executa um refresh completo, e o segundo, que utiliza Ajax.

* Código que utiliza Synchronous Server Roundtrip (refresh no browser)
DropDownChoice ddEstados = new DropDownChoice("estados", estados) {
protected boolean wantOnSelectionChangedNotifications() {
return true;
}

protected void onSelectionChanged(final Object newSelection) {
String estado = (String) newSelection;
ddCidades.setChoices((List) cidades.get(estado));
}
};


O método wantOnSelectionChangedNotification deve retornar true, para que o Wicket possa saber que deve gerar um Javascript no HTML de saída, para que seja feito um submit do formulário, sem executar o ciclo de vida do Form. O framework nem atualiza os Models dos componentes, mas mantém o estado da página. Por fim executa o metodo onSelectionChanged(Object) do objeto que sofreu a alteração.

* Código que utiliza Asynchronous Server Roundtrip (AJAX)
DropDownChoice ddEstados = new DropDownChoice("estados", estados);
ddEstados.add(new AjaxFormComponentUpdatingBehavior("onchange") {
protected void onUpdate(AjaxRequestTarget target) {
String estado = (String) ddEstado.getModelObject();
ddCidades.setChoices((List) cidades.get(estado));
target.add(ddCidades);
}
});


Aqui é dito que o componente ddEstados recebe um IBehavior, que será disparado no evento onchange do componente. É importante lembrar que o onchange é do Javascript, e não algo específico do framework.
Quando o Wicket submete a chamada Ajax, ele atualiza a nova seleção, antes de executar o método onUpdate. Por esta razão, é possível acessar o novo valor pelo getModelObject(). Feito isto, as cidades daquele estado são filtradas e a nova lista, atualizada na combo de Cidades. A chave para esta funcionalidade, está na linha
target.add(ddCidades);
Esta chamada indica que este componente deve ser renderizado e atualizado, via Ajax, no HTML. O próprio framework se encarrega de todo o trabalho! Qual a dificuldade? Conhecer a API do Framework... :)

Notaram que... o código HTML não sofreu alteração? ;)

Vejamos alguns números:
  • Código HTML: não sofreu alteração.
    6 linhas escritas pelo programador (LEPP).
  • Código JavaScript: gerado pelo framework; (programador não precisa conhecer JS).
  • Código Java: plain Java. Exige apenas conhecimento da linguagem Java, POO e a API do Framework (como qualquer outro framework)
    Non-Ajax: 9 LEPPs
    Ajax: 8 LEPPs
  • Código XML: zero
  • Uso de Tag Libraries: zero. Wicket não usa essa tecnologia. =)
  • Uso de outros frameworks: zero. Desenvolver Ajax com Struts, por exemplo, geralmente exige integração com DWR, ou outros frameworks similares.

"Welcome to Wicket... Plain Java, Plain HTML... this is Web Development!"

Link para este post

09 Outubro 2007

Wicket in Action: Primeiro Capítulo


Já encontra-se disponível (a algum tempo...) gratuitamente o primeiro capítulo do livro Wicket in Action, série essa de livros técnicos de alta qualidade da Editora Manning.

O livro é assinado por dois dos principais commiters do framework, Eelco Hillenius e Martijn Dashorst. Conferi e posso dizer que o nível de informação está acima das minhas expectativas. Para quem não conhece o framework, esta leitura já elimina muitas dúvidas (mas criam-se novas! a curiosidade mata...).

Outros 4 capítulos já estão prontos, mas estes somente à venda pelo site da Manning.

Link para este post

06 Outubro 2007

Wicket aguenta peso pesado

Parece que o mito de que Wicket não serve para sites de grande porte começou a ser desmistificado. O site Thoof.com lançado recentemente e que veio para concorrer com o Digg.com, deve servir como prova de que Wicket está maduro e robusto o suficiente para suportar grande quantidade de usuários, assim como conteúdo.

E parece que o pessoal do Thoof acredita mesmo nisso, pois já criaram até uns vídeos para pegar no pé do pessoal do Digg...



A atenção que a comunidade começou a dar ao framework é tanta que a IBM preparou um tutorial de como desenvolver aplicações Wicket no Apache Gerônimo. Vale lembrar que o framework já é um projeto graduado na própria Apache!

[]'s !
miojo

Link para este post

12 Junho 2007

Wicket: Highlight current Menu with Generics!

Yeah! The title sounds weird, but it's something really cool. The idea is to do less if/else as possible to select the current menu.

This is what my Template.html looks like:

        <!-- menu -->   
<div id="menu">
<ul>
<li wicket:id="system">
<a wicket:id="link" href="System.html">System</a>
</li>
<li wicket:id="about">
<a wicket:id="link" href="About.html">About</a>
</li>
</ul>
</div>

So, yes there is some CSS behind to show a cool layout, but that is not the point. Just note that if a <li> has an id of "current" like this:
    <li id="current">...</li>

Imagine that the CSS setup will do the rest, throwing out some cool stuff to highlight the current/selected menu.

So, how any pages under System's menu tells Template that they belong to it? As simple as this:
class UsersCRUD extends Template<System> {
}

Done! How this works? Let's check what's happening inside Template's default constructor:
public abstract class Template<M> extends WebPage {
public Template() {
Class<M> clazz = (Class<M>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];

add(new MenuItem("system", System.class, clazz));
add(new MenuItem("about", About.class, clazz));
}
}

And here goes the code for MenuItem:
public class MenuItem extends WebMarkupContainer {
/* Here the magic happens with CSS... */
public String getMarkupId() { return "current"; }

public MenuItem(String id, Class<? extends Template> linkTo,
Class<? extends Template> currentGeneric) {
super(id);

boolean isCurrentPage = currentGeneric.equals(linkTo);
setOutputMarkupId(isCurrentPage);
add(new BookmarkablePageLink("link", linkTo));
}
}

How about that? One simple equals and the conditional menu is done!

Oh, don't forget that Template is an abstract page and so, it has somewhere a <wicket:child/> so UserCRUD can be a subclass and do a composite page through inheritance.

Have fun Wicketers!!

Link para este post

08 Maio 2007

Wicket: AJAXiando a Paginação

No penúltimo post, mostrei como implementar paginação de listas com o framework Wicket. Agora, visando maior produtividade e usabilidade na interface, apresento-lhes o que é preciso para implementar a mesma paginação ajaxiada.

O processo é o mesmo, já que o framework é component-based. As alterações no HTML são mínimas e mesmo em Java, o que será preciso modificar é qual componente instanciar para tratar a ListView. Mas por se tratar de uma implementação Ajax, algumas considerações e explicações devem ser feitas antes.

  • Ao implementar algo em Ajax, as vezes é preciso de uma área (div) para ser atualizada pelas requisições assíncronas com novo código HTML produzido dinâmicamente no servidor.
  • No caso da ListView, é importante que a tabela fique dentro de uma área como esta.
  • Em Wicket, é possível referenciar uma área qualquer div através do componente WebMarkupContainer.
Uma das enormes vantagens de utilizar o framework Wicket, é poder desenvolver diversas funcionalidades sem escrever uma linha de Javascript qualquer. Seu suporte a Ajax está muito estável para funcionalidades básicas, e ainda existe o projeto Wicket Extensions que provê muitos outros componentes 100% plugáveis a qualquer aplicação Wicket. Cada componente expõe no HTML de alguma forma, o Javascript necessário para que o mesmo funcione, como os de Ajax por exemplo. Em outro post, mostrarei como implementar componentes reutilizáveis (e aí sim, teremos que escrever Javascript se for o caso).

Seguindo o assunto do post, vamos ao que interessa: ajaxiar uma paginação. Abaixo, está o código da tela utilizada na explicação anterior:

Pessoas.html
<table>
<tr>
<td>nome</td>
<td>idade</td>
</tr>
<tr wicket:id="lista">
<td><span wicket:id="nome">foo</span></td>
<td><span wicket:id="idade">12</span></td>
</tr>
<tr>
<td colspan="2">
<span wicket:id="navegacao">Aqui vai a barra de navegacao</span>
</td>
</tr>
</table>

A única alteração que devemos fazer, é colocar esta tabela dentro de uma área atualizável por requisição Ajax: um div. Ou seja, ficará assim:

<div wicket:id="ajaxTable">
<table>
<tr>
...
</tr>
</table>
</div>


Feito isto, é preciso que o componente ajaxTable seja reconhecido pelo Wicket na classe Pessoas. E é agora que utilizaremos a classe WebMarkupContainer:

Pessoas.java
public class Pessoas extends WebPage {
public Pessoas() {
List listaPessoas; /* obtem de algum lugar (Spring talvez) */
PageableListView view = new PageableListView("lista", listaPessoas) {
protected void populateItem(ListItem item) {
Pessoa p = (Pessoa) item.getModelObject();
item.add(new Label("nome", p.getNome());
item.add(new Label("idade", p.getIdade());
}
};

WebMarkupContainer ajaxTable = new WebMarkupContainer("ajaxTable");
ajaxTable.setOutputMarkupId(true); // obrigatorio pq nao tem o
// atributo id com mesmo
// nome no html
add(ajaxTable);

// O componente PageableListView está dentro do

// entao deve ser adicionado ao WebMarkupContainer, não à página.
ajaxTable.add(view);

// O componente-chave para paginação-ajax, está aqui:
ajaxTable.add(new AjaxPagingNavigator("navegacao", view));
}
}
Pronto! Paginação ajax habilitada com sucesso! :)
Desta forma, ao navegar na lista somente a tabela com os dados será atualizada, através de requisições Ajax. Esta funcionalidade é muito útil quando se tem telas pesadas com diversos componentes, e não queremos atualizar a página inteira, ou quando simplesmente queremos dizer que a aplicação é Web 2.0 compliant.

Explicando um pouco o que foi feito:
  • Não foi preciso alterar qualquer trecho de código na table html, mas é necessário que a mesma esteja numa área atualizável div.
  • Não existe um AjaxPageableListView. O mesmo que utilizamos no primeiro exemplo foi utilizado aqui.
  • Como existe um div para ser atualizado assíncronamente, este precisa ser referenciado por um WebMarkupContainer, que conterá o novo código HTML após a requisição Ajax e substituirá o código anterior.
  • Qualquer componente que esteja dentro do div, deve ser adicionado no MarkupContainer, respeitando a árvore de componentes.
  • Configurei a propriedade
    outputMarkupId
    porque no HTML, nao coloquei o atributo id manualmente. Este método faz apenas isto. Utiliza o nome do componente para o atributo id.
  • Tanto a ListView como o Navigator, são adicionados no MarkupContainer.
  • Para a paginação efetivamente funcionar, deve-se utilizar o componente
    AjaxPagingNavigator
  • Pronto!
Até a próxima!

Link para este post

03 Maio 2007

Apache Wicket: agora é oficial!

Tenho o prazer em anunciar o primeiro lançamento do Apache Wicket. Este release atende a todos os requisitos do Incubator PMC, e por isso, podemos considerar este o primeiro grande passo para o amadurecimento do framework, que a partir de agora, receberá maior atenção pela comunidade Java e Open Source. :)

Antes de anunciar para os brasileiros, um pouco da introdução (para aqueles que não leram meu primeiro post:

-= Apache Wicket =-
Apache Wicket é um framework web orientado a componentes, no momento sob os cuidados da Apache Software Foundation e sua incubadora. Com distinção entre lógica e código HTML, um modelo de dados em POJOs e ser livre de XML, o Apache Wicket simplifica e diverte o desenvolvimento de aplicações Web. Facilite seu desenvolvimento trocando complexidade por um poderoso mecanismo de reutilização de componentes escritos em puro Java e HTML.

Vocês podem encontrar outras informações aqui: http://incubator.apache.org/wicket

-= Este lançamento =-
Este é o primeiro de uma série de betas antes de uma confiança maior do time para finalizar o Apache Wicket 1.3 e lançá-lo sem bugs. Considere-o um Release Candidate.

- Migrando do Wicket 1.2 -
Aos que já utilizam o Wicket 1.2, o guia de migração para Wicket 1.3 encontra-se disponível no seguinte endereço: http://cwiki.apache.org/WICKET/migrate-13.html

- Download -
Este lançamento pode ser baixado no seguinde endereço:
http://people.apache.org/dist/incubator/wicket/apache-wicket-1.3.0-incubating-beta1/dist/

- Download com Maven -
Repositório:
http://people.apache.org/dist/incubator/wicket/apache-wicket-1.3.0-incubating-beta1/m2-repo/

- Bugs -
No caso de bugs serem encontrados, pedimos que submetam os mesmos no JIRA:
http://issues.apache.org/jira/browse/WICKET

Caso queira contribuir enviando patches de bugs, utilize a seguinte tag:
http://svn.apache.org/repos/asf/incubator/wicket/tags/wicket-1.3.0-incubating-beta-1/

-= Incubadora Apache Wicket =-
Maiores informações sobre o andamento do processo na incubadora:
http://incubator.apache.org/projects/wicket

[]'s!!
miojo

Link para este post

28 Abril 2007

Wicket: Paginando listagens em 3 passos

Um dos pontos que mais se apanha para implementar quando do desenvolvimento de aplicações Web, é a paginação de lista de dados. Lembro-me dos tempos de Struts, onde a grande dúvida era usar ou não usar a antiga Display Tag. Infelizmente, trabalhando com frameworks action-based e código view em JSP/Taglib, implementar paginação é uma das tarefas mais chatas para a interface Web, pois exige uma cacetada de configuração na página e principalmente: suja todo o HTML e pronto, lá se foi o protótio do cliente e o designer não pode mais editar com um preview em mãos.

Algumas pessoas comentaram no primeiro post sobre Wicket pedindo que eu desse maiores detalhes de como funciona ou como se utiliza. Pensei bastante e achei melhor primeiro apresentar como o desenvolvedor utiliza o framework, antes de se preocupar em como o mesmo funciona "por trás das cortinas".

Para começar a enteder a paginação, primeiramente é importante entendermos o funcionamento do componente básico de repetição: ListView. Vejam o exemplo a seguir:

Pessoas.html

<table>
<tr>
<td>nome</td>
<td>idade</td>
</tr>
<tr wicket:id="lista">
<td><span wicket:id="nome">foo</span></td>
<td><span wicket:id="idade">12</span></td>
</tr>
</table>


Pessoas.java
public class Pessoas extends WebPage {
public Pessoas() {
List listaPessoas; /* obtem de algum lugar (Spring talvez) */
add(new ListView("lista", listaPessoas) {
protected void populateItem(ListItem item) {
Pessoa p = (Pessoa) item.getModelObject();
item.add(new Label("nome", p.getNome());
item.add(new Label("idade", p.getIdade());
}
});
}
}

Entendendo o funcionamento do ListView:
  • O bind foi feito com a tag <tr>, então para cada iteração na List, o ListView vai processar um ListItem para aquela tag.
  • O framework possui hierarquia de componentes, então vejam que o Label é adicionado no ListItem e não na ListView. Isto porque no HTML, temos e nome e idade dentro da lista.
  • Para cada objeto na lista, o framework coloca ele como ModelObject do ListItem. (farei um post futuramente sobre Models, explicando seu funcionamento e os diversos tipos).
O interessante aqui é enteder o básico do funcionamento da ListView, que pode ser aplicado a praticamente qualquer tag html que se deseja iterar e repetir.

Agora, vamos adicionar paginação nesta ListView. Para isto, precisamos executar alguns passos:
  1. Editar o HTML e acrescentar a barra de navegação.
  2. Converter a ListView para uma PageableListView.
  3. Adicionar em Java o componente PagingNavigator, realizando binding entre ele e a barra de navegação.
Passo 1
Utilizaremos aqui uma barra de navegação default do Wicket, sem customização. Deve-se adicionar na tabela a seguinte TR:
<tr>
<td colspan="2">
<span wicket:id="navegacao">aqui vai a barra de navegacao</span>
</td>
</tr>
Passo 2
Alterar a instanciação de uma ListView para uma PageableListView. Feito isto, é preciso informar no construtor, quantos itens serão apresentados por página:
PageableListView listView = null;
add(listView = new PageableListView("lista", listaPessoas, 2) { ...

Passo 3
Agora, falta apenas colocar o componente de navegação na classe Java:

     add(new PagingNavigator("navegacao", listView));

Pronto! Só reparem que no construtor de PagingNavigator, é preciso passar a referência para o PageableListView que será paginado por ele.

O que aprendemos?
Que utilizando Wicket, não sujamos nosso código HTML, nem mesmo para fazer paginação! É possível manter o HTML limpo para que os designers possam trabalhar sem problemas, e também, que nós programadores tenhamos apenas um ponto para modificar, como neste exemplo onde alteramos de uma simples listagem para uma listagem paginada, o controle dinâmico das telas: a classe Java! Pois em Wicket não existe configuração em XML. Este é todo o código necessário para que esta paginação funcione.

Confiram mais exemplos aqui:
Wicket Repeater Views

Até a próxima!

[]'s!
miojo

Link para este post

26 Abril 2007

Wicket - Apresentação SouJava

Ano passado fiz uma apresentação sobre Wicket no SouJava em São Paulo, mas infelizmente não teve uma audiência muito grande, devido provavelmente ao pequeno público interessado em conhecer um framework Web com nome tão estranho. :)

(se eu fizer outra agora hoje, acredito que irá mais gente!)

Então, publico aqui os slides que mostrei na época, para dar uma idéia melhor do funcionamento e espero que acompanhem mais de perto o crescimento do Wicket!



[]'s!!!
miojo

Link para este post

23 Abril 2007

Wicket! ... Hein?

Muitos dos meus amigos estranharam ao pronunciar essa palavra, Wicket. E até concordo que é estranha, mas apesar do nome, que agora mudou para... Apache Wicket, acredito que a credibilidade só de ouvir o nome aumentará consideravelmente.

O que é o Wicket?

Resumindo: é tudo o que queríamos que um framework Web fosse! :D Pode parecer um exagero, mas depois de desenvolver algumas telas, vocês verão que não estou mentindo aqui. É realmente divertido, rápido e prático, desenvolver aplicativos Web 2.0 com ele. Tão fácil quanto desenhar tela Swing no Matisse! O framework tem alguns conceitos parecidos com o Tapestry, então quem é familiar com este (também mantido na Apache ), vai pegar rápido a idéia.

É parecido com o Struts/JSF?

Graças a Deus... não!! Trabalhei com Struts durante 2 anos e meio, e recentemente me arrisquei a usar JSF para uma ferramenta interna, e minha conclusão? Struts == JSF = true; Ou seja, se eu já não gostava de Struts, JSF definitivamente não me agrada muito. Apesar disso, essas duas tecnologias são fortes e devem ser respeitadas. Agora, quanto ao Wicket, devo dizer que ele preenche lacunas que antes Struts/JSF nos deixavam extremamente irritados.

Conhecem o termo SOP? Não, não digitei errado SOAP. Acontece que desenvolver aplicativos Web com Struts/JSF, a gente acaba entrando numa metodologia chamada String Oriented Programming. Onde temos que localizar num arquivo xml o retorno de um método, para saber para onde vai aquele maldito... return "success";. Não apenas isso, mas em muitos outros casos como bind de componentes da página, atributos e campos, com o que você está codificando em Java.

Então, o que ganho?

Um desenvolvimento prático e 99,9% separando o que é código dinâmico e o que é código estático (leia-se: Java, HTML, JavaScript). Essa é apenas uma das inúmeras vantagens que se obtém utilizando Wicket para desenvolver aplicações Web. Mas de início, comento aqui esta vantagem.

O seu designer terá total liberdade para mexer no design, layout e estrutura (no caso da estrutura, existem limites, claro), sem ferrar com o código dinâmico, pois este fica em um arquivo separado. Que tipo de arquivo é esse? Adivinha: .java! Sim, para cada página existe uma classe Java para controlar os componentes dinâmicos e estado que esta terá durante o fluxo do site. Isso dá ao designer, preview direto no browser, sem aquelas tags malucas de Struts/JSF ou Velocity, que detonam com o Dreamweaver, Nvu e outros WYSIWYG. Tudo isso graças a um HTML limpo de tags. É possível desenvolver um website, utilizando o protótipo que o cliente enviou, fazendo algo em torno de 5% a 15% de alterações no código HTML, e mantendo-o totalmente funcional direto no browser.


Vamos ver um exemplo de uma página Wicket (aquele infernal Hello World):


<html>

<head><title>Hello Wicket</title></head>

<body>

<span wicket:id="usuario">Bruno Borges</span>

</body>

</html>


E aqui, a classe Java colocando um valor diferente no componente usuario:


public class UsuarioPage extends WebPage {

public UsuarioPage() {

add(new Label("usuario", "Nissim Miojo"));

}

}


Abrindo o arquivo UsuarioPage.html temos um preview puro de uma página estática com o conteúdo Bruno Borges. Agora, se executarmos através do framework Wicket, o conteúdo Nissim Miojo substituirá o valor de protótipo do componente usuário. No que isso é bom? Manter um protótipo funcional e facilitar que o designer faça alterações sem ferrar com o código! :D

E o que mais?

Tem muito mais! Mas agora está tarde, e vou dormir. Quando me inspirar outra vez, posto mais coisas!


[]'s!!
miojo

Link para este post