Caelum | Ensino e Inovação - Cursos de Java, Scrum, Ruby on Rails


Nova versão da Apostila FJ-28 liberada com VRaptor 3.1

Por Lucas Cavalcanti em 13/01/10

Depois de mais de 4000 downloads nesses 3 meses de vida, lançamos o VRaptor 3.1 com muitas novidades e bugfixes, com destaque ao suporte aos novos recursos das servlets no Java EE 6, o que permite usar o VRaptor 3 sem nem mesmo um web.xml em containers compatíveis com servlets 3.0, além de novos recursos para AJAX, lógicas genéricas e facilidades no mapeamento de URLs, forwards e redirects.

vraptor apostila

Aproveitando o lançamento dessa nova versão do framework, estamos disponibilizando a atualização da apostila do curso FJ-28 de VRaptor, Hibernate e AJAX, que já está disponível para download. O material não abrange apenas VRaptor, Hibernate e JSP, mas também entra em detalhes de como fazer a costura de maneira correta, gerenciando suas Sessions, Transactions, etc, através da criação de uma webapplication desde o zero.

  • Share/Bookmark

Escrevendo e migrando aplicações para o Google App Engine

Por Pedro Matiello em 17/11/09

Recentemente migramos nosso site para o Google App Engine (GAE), o serviço de cloud computing do Google, fazendo uso do suporte a aplicações Java. A ideia é que você desenvolva sua webapplication normalmente e faça o upload do war para os servidores do Google usando um SDK, que também possui um servidor local para desenvolvimento. Pronto! Sua aplicação web agora oferece alta escalabilidade e disponibilidade.

Algumas restrições existem, no entanto. Vamos passar por elas e comentar cada uma, que no início podem ser uma barreira para o desenvolvedor. Para começar, há uma whitelist especificando as classes do Java que são suportadas. As classes da biblioteca padrão não listadas são bloqueadas. Pode parecer inconveniente, mas estas limitações são necessárias para garantir a segurança e escalabilidade do serviço — basta lembrar que uma mesma máquina é dividida entre muitas aplicações, e que cada aplicação pode estar rodando em um grande número de servidores.

O Google App Engine também não permite que novos arquivos sejam criados pela aplicação no servidor, já que isso poderia implicar em problemas de sincronização entre os sistemas de arquivos de suas muitas instâncias. Também não é oferecido um banco de dados relacional, mas sim uma datastore sobre o BigTable, que pode ser acessada pelas APIs do JDO e da JPA. Relacionamentos many-to-many, consultas com join, agregações (sum, avg, max, etc) e polimórficas não são suportadas, mas a maior parte das demais operações funciona como de costume sem a necessidade de maiores mudanças. Trata-se de uma característica comum dos bancos de dados não-relacionais, que abrem mão de algumas funcionalidades para obter maior desempenho, escalabilidade e disponibilidade. Pode ser trabalhoso migrar de um banco de dados relacional para o BigTable, além de ser uma tecnologia proprietária do Google.

Outra limitação importante é a impossibilidade de criar sockets e Threads. Todavia, o App Engine possui mecanismos próprios que permitem a realização de requisições HTTP e o envio de emails (com restrições na especificação do remetente). Em breve uma API de agendamento de tarefas será disponibilizada para o Google App Engine Java.

Ainda, o suporte a Expression Language vem desativado por padrão. Para ativá-lo, é necessário adicionar a seguinte linha em todos os arquivos JSP que fazem uso de EL:
<%@ page isELIgnored="false" %>

No caso de arquivos de tags, deve-se adicionar:
<%@ tag isELIgnored="false" %>

A tag <include-prelude> no web.xml também é ignorada, mas é possível contornar o problema adicionando algo como a linha abaixo no começo dos arquivos JSP:
<%@ include file="../prelude.jspf" %>

Um problema de outra é ordem é a inicialização e a manutenção das instâncias, conhecido como cold start. Quando sua aplicação é chamada pela primeira vez, várias instâncias são produzidas de forma distribuída pelos servidores da nuvem. Este processo é bastante lento, podendo consumir vários segundos, e depende também da velocidade do contexto da sua aplicação web. Os acessos seguintes são respondidos com baixa latência, mas, após um período de inatividade, as instâncias são destruídas, exigindo que todo o lento processo de inicialização seja refeito pelo serviço em um próximo acesso. Para evitar isso, a prática mais comum tem sido usar o agendador de tarefas do próprio App Engine para visitar alguma página do site a cada poucos minutos — e esta é uma solução que também possui seus problemas.

Por causa da grande quantidade de componentes restritos, muitos frameworks, como Spring, implementações de JSF, mapeadores XML, exigem ajustes para rodar no GAE. O mesmo se aplica ao VRaptor 3 e, para facilitar o trabalho dos usuários, muitos deles oferecem uma versão voltada para o uso no Google App Engine, incluindo todas as alterações necessárias. No caso do VRaptor 3, você pode obter um blank-project pro GAE na página de downloads e usa-lo como esqueleto de um novo projeto, que pode ser facilmente importado e modificado no Eclipse (existe um plugin do Google bastante prático, mas um build.xml adequado ao GAE é uma alternativa bastante razoável).

Em post anterior, o Paulo Silveira já havia falado, de forma geral, sobre as vantagens de manter sua aplicação no cloud, mesmo quando o volume de requisições não é grande o bastante para se representar um gargalo, como é o nosso caso e pode ser visto pelos paineis de controle do GAE:

Gráfico de requisições por segundo no www.caelum.com.br

Requisições por segundo no www.caelum.com.br

Sobre o Google App Engine, em particular, vale ainda acrescentar que a administração é bastante simples, com relatórios e estatísticas apresentados de forma coerente, e também que é possível executar múltiplas versões da sua aplicação facilmente. O serviço ainda é beta e tem seus problemas ocasionais, mas, até o momento, tem se comportado de forma bastante satisfatória. Considere o uso do cloud para sua próxima aplicação e livre-se de boa parte da preocupação com hardware, grids, clusters e infraestrutura.

  • Share/Bookmark

Mirror DSL: facilitando o uso da API de reflection

Por Jonas Abreu em 17/11/08

No último domingo foi feito o primeiro release público do projeto Mirror (versão 1.2).

O Mirror é um projeto que tem por objetivo facilitar o uso da Java Reflection API, removendo boa parte da burocracia (como as diversas checked exceptions que são lançadas) e utilizando uma DSL para melhorar a legibilidade do código.

Com essa remoção de burocracia e a DSL, é possível transformar o seguinte código:

Field toSet = null;
for (Field f : target.getClass().getDeclaredFields()) {
    if (f.getName().equals("field")) {
        toSet = f;
    }
}
if (toSet != null && ((toSet.getModifiers() & Modifier.STATIC== 0)
        && ((toSet.getModifiers() & Modifier.FINAL== 0)) {
    toSet.setAccessible(true);
    toSet.set(target, value);
}

em algo mais legível e expressivo:

Mirror.on(target).set().field("fieldName").withValue(value);

Atualmente o Mirror possui suporte para lidar com as operações reflectivas mais comuns (como instanciar objetos, invocar métodos, ler ou escrever atributos, etc). Ele foi desenvolvido por Adriano Almeida, Diego Feitosa e eu, todos consultores/instrutores aqui da Caelum, enquanto enfretavamos problemas comuns no dia a dia.

Esperamos que possa ser útil para vocês também!

  • Share/Bookmark

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.

  • Share/Bookmark



Caelum | Ensino e Inovação
São Paulo: Rua Vergueiro, 3185, cj. 87, próximo ao Metrô Vila Mariana   |   Tel. (11) 5571-2751
Rio de Janeiro: Rua Senador Dantas, 80, cj. 307/308 - Centro   |   Tel. (21) 2220-4156 ou 2297-0033
Brasília: SCS Qd. 8 Bl. B-50, Sala 521 - Ed. Venâncio 2000   |   Tel. (61) 3039-4222