Novidades no material do curso FJ-26 Web Avançado com Hibernate e JSF

Por Guilherme Silveira em 21/08/07

Durante o último mês, fizemos uma grande revisão na apostila do nosso curso FJ-26, Laboratório de MVC com Hibernate e JSF para a Web. O material foi reescrito, as tecnologias atualizadas e o conteúdo revisado e estendido. A apostila agora conta com muito mais páginas que a anterior, com mais explicações, códigos de exemplo, exercícios e gráficos.

Esse curso é um Laboratório Avançado de programação para Web com as boas práticas do MVC aplicando Hibernate e JSF, duas tecnologias líderes de mercado.

Dentre as novidades estão o uso de APIs e recursos avançados do Hibernate (como Extra Lazy, Detached Criteria, batch) e o uso de JSF 1.2 com a RI, RichFaces e Ajax4JSF. Além disso, estamos usando Eclipse 3.3 e WTP 2.0. no nosso curso. A parte de relatórios também foi atualizada para usar o Birt do projeto Eclipse.

As nossas próximas turmas do FJ-26, do dia 25 de agosto e 10 de setembro, já serão com o novo material e novas tecnologias.

A Caelum tem uma preocupação constante com o material utilizado nas aulas, no sentido de deixá-lo sempre atualizado e de acordo com as novas tecnologias do mercado.

i18n: Internacionalização com JSTL

Por Fabio Kung em 13/08/07

A origem do termo i18n é bastante curiosa. Pessoas preguiçosas (como eu) odeiam ter que ficar escrevendo palavras grandes como internationalization. Adivinha quantas letras existem entre o i e o n?

A mesma idéia foi usada para localization: l10n.

Internacionalizar aplicações web é cada vez mais uma tarefa corriqueira de todo desenvolvedor web. Comumente as pessoas me perguntam como fazer para ter aquelas bandeiras no topo do site, que mudam a lingua do sistema inteiro (exemplo na aplicação demo do VRaptor).

A maioria dos frameworks web tem a sua maneira particular de prover esse mecanismo, mas o que muita gente desconhece é que existe uma forma padrão de fazer isso, definida na especificação do Java EE, através da JSP Standard TagLibs.

1. Escolha uma implementação

JSTL é apenas uma especificação, portanto é necessário o uso de uma de suas implementações. A mais usada é a Jakarta Standard, que você pode baixar diretamente do site da Apache.

Certifique-se de que esteja baixando alguma implementação da versão 1.1 da JSTL (ou superior). Não garanto que irá funcionar com versões mais antigas. Essa versão 1.1 da JSTL requer o uso de, no mínimo, a versão 2.4 da especificação de Servlets. Portanto certifique-se de configurar corretamente a versão no seu web.xml. Perceba o version="2.4" no exemplo abaixo:

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="MinhaWebApp" version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <display-name>Minha aplicação</display-name>

  <!-- Resto das coisas ... -->

</web-app>

Basta descompactar o zip que foi baixado e colocar o jstl.jar (jar da especificação) e o standard.jar (implementação) no diretório WEB-INF/lib da sua aplicação web.

2. Configure um arquivo de mensagens

Para dizer à JSTL qual será o arquivo que contém as mensagens do seu sistema, basta adicionar a seguinte configuração ao seu web.xml:

<web-app id="MinhaWebApp" version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
         http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <display-name>Minha aplicação</display-name>
  
  <context-param>
    <param-name>
      javax.servlet.jsp.jstl.fmt.localizationContext
    </param-name>
    <param-value>messages</param-value>
  </context-param>
  
  <!– Resto das coisas … –>
</web-app>

Este arquivo de mensagens deve estar no classpath da sua aplicação web e deve possuir a extensão .properties. Existem várias formas de se fazer isso. A mais simples, é criar o arquivo messages.properties no diretório onde estão os fontes (*.java) da sua aplicação (comumente esse diretório se chama src).

Certifique-se também de não colocar este arquivo dentro de nenhum pacote. Se fosse mesmo necessário deixá-lo dentro de algum pacote, a configuração no web.xml mudaria um pouco:

<param-value>br.com.empresa.pacote.messages</param-value>.

3. Deixe todas as mensagens (e labels) do seu sistema no arquivo de mensagens

Comece colocando as mensagens no arquivo messages.properties:

site.titulo = Sistema com i18n
saudacao = Bem vindo ao sistema

campo.nome = Nome:
campo.email = Email:
campo.rua = Rua:
campo.cidade = Cidade: 

botao.enviar = Enviar
botao.cancelar = Cancelar

erro.campo.obrigatorio = Por favor, preencha o campo
# etc ...

Agora, para usar essas mensagens nas suas páginas JSP, basta usar a taglib fmt da JSTL:

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<html>
<head>
<title><fmt:message key="site.titulo"/></title>
</head>
<body>
  <h1><fmt:message key="site.titulo"/></h1>
  <p><fmt:message key="saudacao"/></p>

  <form>
    <fmt:message key="campo.nome"/>
    <input type="text" name="nome" /><br/>

    <fmt:message key="campo.email"/>
    <input type="text" name="email" /><br/>

    <fmt:message key="campo.rua"/>
    <input type="text" name="rua" /><br/>

    <fmt:message key="campo.cidade"/>
    <input type="text" name="cidade" />
    <p><input type="submit"
              value='<fmt:message key="botao.enviar"/>'></p>
  </form>
</body>
</html>

4. Traduza o sistema para mais línguas

Para fazer com que o sistema possa funcionar com diferentes línguas, basta criar novos arquivos de mensagens, um para cada lingua diferente. Por exemplo, para traduzir o sistema para o alemão:

# arquivo messages_de.properties
site.titulo = System mit i18n
saudacao = Herzlichen Willkommen

campo.nome = Name:
campo.email = Email:
campo.rua = Strasse:
campo.cidade = Stadt: 

botao.enviar = Senden
botao.cancelar = Abbrechen

erro.campo.obrigatorio = Das ist ein benötige Feld
# etc ...

E para ter uma versão em inglês do sistema:

# arquivo messages_en.properties
site.titulo = i18n system
saudacao = Welcome

campo.nome = Name:
campo.email = Email:
campo.rua = Street:
campo.cidade = City: 

botao.enviar = Send
botao.cancelar = Cancel

erro.campo.obrigatorio = Required field
# etc ...

Estes arquivos devem estar no mesmo diretório do arquivo de mensagens padrão: messages.properties.

A tag fmt:message sempre procura o arquivo de mensagens mais adequado para o Locale associado ao usuário. No início, o Locale do usuário é aquele que está configurado no browser. Os navegadores enviam no cabeçalho das requisições quais são as línguas preferidas pelo usuário. Experimente mudar essas configurações no seu navegador e ver que o sistema passa a ser exibido em línguas diferentes.

Se o Locale associado usuário for en_US (inglês dos EUA), a tag fmt:message irá tentar buscar as mensagens nos seguintes arquivos, em ordem:

  • messages_en_US.properties
  • messages_en.properties
  • messages.properties

O primeiro a ser encontrado será usado. Portanto, a boa prática é ter o arquivo messages.properties com a língua padrão do sistema e um arquivo específico para cada língua adicional.

5. Mude a língua do sistema a força

Para fazer com que o sistema passe a ser exibido em uma língua diferente da que o browser pediu, basta trocar o Locale associado ao usuário.

Para tal existe uma tag da JSTL, a fmt:setLocale, que pode ser usada junto com um c:if em uma página mudaLingua.jsp, por exemplo:

<c:if test="${not empty param.lingua}">
  <fmt:setLocale value="${param.lingua}" scope="session"/>
</c:if>

Basta agora chamar essa página passando o locale adequado. Experimente chamar mudaLingua.jsp?lingua=de e mudaLingua.jsp?lingua=en e ver o sistema ser exibido em outra lingua.

Parece um pouco estranho ter um jsp responsável pela tarefa de mudar a língua do sistema, já que os jsps deveriam ser responsáveis apenas pela apresentação (geração de html, no nosso caso). A funcionalidade parece se encaixar melhor dentro de uma classe responsável por mudar a lingua do sistema.

A classe javax.servlet.jsp.jstl.core.Config serve justamente para controlar as configurações da JSTL programaticamente. Com isso, você pode ter uma servlet, uma action do struts, uma lógica do vraptor, ou algo similar para mudar a lingua do seu sistema.

Exemplo com uma servlet:

public class MudaLinguaServlet extends HttpServlet {
  @Override
  protected void service(HttpServletRequest request, HttpServletResponse response)

      throws ServletException, IOException {
        String language = request.getParameter("lingua");
        Locale locale = new Locale(language);

        Config.set(request.getSession(), Config.FMT_LOCALE, locale);
        Config.set(request.getSession(), Config.FMT_FALLBACK_LOCALE, locale);

        
        response.sendRedirect("index.jsp");
  }
}


Basta agora chamar a servlet passando o parâmetro lingua. Experimente chamar mudaLingua?lingua=en e mudaLingua?lingua=de. Ou você pode ainda deixar bandeiras para diferentes países com links para essa Servlet que muda a língua.

Metodologias ágeis, XP, Scrum, podcasts

Por Sérgio Lopes em 08/08/07

A Caelum ultimamente tem se voltado bastante para metodologias ágeis com XP e Scrum. Começamos a usar XP nos nossos projetos internos, como contamos antes. E temos agora um novo treinamento de Scrum com Alexandre Magno.

Seguindo essa tendência, essa semana saiu um podcast em que o Guilherme Silveira falou para a ImproveIT sobre as experiências da Caelum com XP, passando vários detalhes de como implementamos essa metodologia nos projetos da empresa. Clique aqui para ouvir o podcast direto na ImproveIT.

Além disso, o Alexandre Magno, instrutor do treinamento de Scrum na Caelum, também já havia participado de um podcast na ImproveIT sobre Scrum e FDD. Clique aqui para acessar o podcast do Alexandre.

E, falando em Scrum, semana passada foi ministrado o primeiro treinamento de Scrum aqui na Caelum com o Alexandre. Eu, Sérgio Lopes, participei do curso, junto com vários outros alunos. Foi excelente, bastante produtivo e interessante. Já estamos inclusive com outra turma agendada para o mês que vem.

Ruby, Capistrano e administração remota

Por Lucas Cavalcanti em 06/08/07

Algumas vezes nos deparamos com a seguinte situação:

Temos uns 15 computadores em rede e precisamos executar um mesmo comando em cada um deles, como por exemplo instalar a JavaVM…

Uma primeira solução seria logar como root máquina por máquina, e executar o comando em todas… Muito ruim…

Agora, se você souber um pouquinho de bash script, em cinco minutos conseguirá fazer um script que loga via ssh em todas as máquinas e executa o comando nelas. Mas ainda tem o problema de você ter que digitar o password para cada máquina, e de ter que assistir a execução do comando, caso ele precise de alguma confirmação, ou algo do tipo…

Felizmente existe uma ferramenta muito útil que pode nos ajudar nessa tarefa entediante. E ela se chama Capistrano (www.capify.org). Com os mesmos 5 min você consegue escrever um script que execute o comando que você quer, digite as confirmações pra você nos lugares necessários, e você só precisará digitar a senha uma única vez!

O Capistrano requer que você o use em sistemas compatíveis com bash, e que exista um mesmo usuário em todas as máquinas que tenha uma única senha.

Para o script funcionar você precisa, com o capistrano instalado corretamente:

  • Definir o usuário a que você vai se conectar nos micros:

    set :user = "root" #pode ser qualquer usuário

  • Definir os ips dos micros aos quais você irá se conectar:

    role :micros = "192.168.0.10", "192.168.0.11"

  • Ou se for uma faixa de IPs:

    role :micros = *("192.168.0.10" .. "192.168.0.25").to_a

  • E, finalmente, definir a tarefa que você quer executar, ou seja, o(s) comando(s). Para isso temos que passar os roles a que queremos nos conectar (os micros)
    task :instalaJava, :roles => :micros do
      run "apt-get install java-virtual-machine"
    end
  • Pronto! O comando será executado em todas as máquinas!
    Ou melhor, quase pronto…
    Você sabe que o apt-get pode pedir confirmação para continuar instalando o programa pedido…
    Você pode automatizar isso usando um recurso muito útil do capistrano:

    run "apt-get install java-virtual-machine" do |channel, stream, data|
      #channel é um objeto que nos permite enviar dados para o comando
      #stream identifica se a saída do comando foi a padrão (:out) ou a de erros(:err)
      #data é uma string com a saída do comando
      if data =~ /Do you want to proceed/ #se na saída do comando tiver essa frase
        channel.send_data "y\\n" #manda pro comando um y e um enter
      end
      puts data #pra saída do comando aparecer na tela
    end

    Agora sim, o script vai fazer o que a gente queria: executar o comando e confirmar!
    O comando run vai ser executado em todos os micros paralelamente, e o bloco de código entre do e end do run vai ser executado toda vez que o comando “apt-get” jogar algum texto na tela ou na saída de erros.

    Pra executar o script basta salvar o código que escrevemos como “capfile” e chamar pela linha de comando cap + o nome da nossa task:

    $ cap instalaJava

    O comando irá mostrar qual task está sendo executado e pedirá uma vez a senha. E é só ficar assistindo, ou ir fazer algo mais produtivo.

    Nesse arquivo capfile você pode usar toda a sintaxe e as funcionalidades de um rakefile e, consequentemente, código em ruby. Então dá pra fazer coisas bem legais, como chamar tasks dentro de tasks, popular um role dinamicamente, executar uma tarefa antes e/ou depois da task chamada, enfim, muitas coisas…

    Você só terá que se preocupar com uma coisa: se um dos micros que estiver no role da task não estiver acessível pela rede, ou se acontecer um erro fatal qualquer, o capistrano não irá executar a task em nenhum dos micros.

    É isso. Divirta-se!

Arquitetura e Design de Projetos Java

Por Paulo Silveira em 01/08/07

Hoje em dia são tantos os design patterns, padrões, frameworks e boas práticas, fica confuso tomar uma decisão. Como devemos desenhar nossas classes? Usar herança ou composição? Injeção de dependências? Webservices, RMI ou um simples arquivo XML? JDBC, JPA ou Hibernate? Devo usar EJB? Quando preciso e como faço um cluster?

Depois de um longo preparo da ementa, exercício e de como abordar tantos tópicos, trazemos a público um novo treinamento, o FJ-91, focado em arquitetura e design de projetos Java. O treinamento passa pelo uso correto da orientação a objetos, design de classes (patterns, domain driven design, componentização), frameworks e especificações, além de Web 2.0 e SOA.

Arquitetura e Desgin de Projetos Java



Os exercícios são apresentados de uma maneira bem diferente: fazemos checkout de inúmeros projetos construídos para este treinamento, com o objetivo de analisar o código, debater, melhorar, e testar os diferentes frameworks e arquiteturas. Desde exercícios simples como trocar herança por composição, até rodar uma aplicação com EJB em cluster. Além de conhecer muitos dos frameworks e novas tecnologias, o intuito é que as pessoas saiam com uma capacitade crítica aguçada para uma tomada de decisão.

Apesar de não ser o foco, cada capítulo apresenta testes simulados para a certificação Sun Certified Enterprise Architect, e também exercícios de modelagem e debates sobre as decisões tomadas, passando pelas três etapas da SCEA. Apesar dessa certificação ser bem antiga e ter um conteúdo ultrapassado em alguns quesitos, os outros tópicos abordados pelo treinamento estão bem mais próximos do Java EE 5.0, o que o torna qualificado para uma possível atualização da prova.

Ao final do treinamento ainda há um capítulo dedicado a tópicos sobre desenvolvimento e metodologias. Alguns papers clássicos são debatidos, como o Silver Bullet e o Mythical Man Month, além dos testes unitários e de aceitação. Ufa! 40 horas de muito trabalho.