Servindo Conteúdo

O App Engine gerencia automaticamente as instâncias de sua aplicação. Novas instâncias são ligadas quando sua aplicação recebe tráfego, e instâncias não utilizadas são desligadas.

Uma instância é um servidor web que é inicializado com as configurações e o código de seu aplicativo. Ele permite que você produza conteúdo dinâmico, por meio de Servlets, páginas JSP ou qualquer outro framework compatível com a especificação Java EE, como o Spring.

Nem todo o conteúdo de sua aplicação muda frequentemente. Arquivos de imagem, como logomarcas ou botões, arquivos de script e folhas de estilo CSS são bons exemplos de recursos que não são alterados com frequência.

Arquivos estáticos

A infra-estrutura do Google App Engine permite que você disponibilize arquivos estáticos utilizando servidores dedicados à esta funcionalidade. Esses servidores são projetados para otimizarem a entrega de conteúdo, utilizando diferentes níveis de cache.

Por padrão, todos os arquivos dentro do diretório src/main/webapp são tratados como arquivos estáticos e como arquivos visíveis para a aplicação: não é necessário realizar configuração extra.

Os arquivos estáticos são mapeados para o caminho físico dos mesmos dentro da pasta src/main/webapp. Isso significa que um arquivo disponível em src/main/webapp/images/logo.png pode ser acessado em sua aplicação pela URL http://localhost:8080/images/logo.png.

Conteúdo dinâmico

Os servlets, como já vimos anteriormente, devem ser mapeados utilizando o arquivo web.xml.

Entretanto, é possível servir conteúdo dinâmico utilizando páginas JSP. Por padrão, as páginas JSP são compiladas em Servlets, e mapeadas automaticamente para o mesmo caminho físico, como os arquivos estáticos.

Isso significa que, se você criar uma página em src/main/webapp/contato.jsp, ela ficará acessível na URL http://localhost:8080/contato.jsp.

Desenvolvendo um website

Vamos utilizar os recursos de conteúdo estático e dinâmico do Google App Engine e desenvolver um pequeno website. Vamos utilizar um template como base, e implementar um formulário de contato utilizando o serviço de envio de e-mails do App Engine.

Utilizando um template

Nosso website será baseado em um template que podemos obter no site Start Bootstrap (http://s.ronoaldo.net/start-bs). Neste site, você encontrará diversos modelos que foram desenvolvidos utilizando o Bootstrap (http://getbootstrap.com/), kit de desenvolvimento de interfaces produzido pela equipe do Twitter.

Para nosso exemplo, vamos utilizar o template Business Casual (http://s.ronoaldo.net/template-business), que já possui as páginas necessárias para nosso objetivo.

Como todo o conteúdo de nosso site será inicialmente estático, vamos apenas extrair o conteúdo do template dentro da pasta src/main/webapp.

Vamos também editar nosso arquivo de mapeamento dinâmico, para incluir mais arquivos na seção <welcome-file-list>:

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

Isso fará com que, ao acessarmos uma pasta de nosso site, os arquivos index.html e index.jsp, se existirem, serão exibidos por padrão.

Visualizando o resultado

Ao recarregar a página, você deverá visualizar o novo template, e os links de navegação devem estar funcionando corretamente.

Implementando um formulário de contato

Para implementarmos o formulário de contato, vamos converter a página estática em uma página dinâmica. Para isso, vamos renomear o arquivo de contact.html para contact.jsp, e adicionar o seguinte conteúdo no início:

<%@ page contentType="text/html; charset=UTF-8"
    language="java" %>
<%@ page import="java.util.Properties" %>
<%@ page import="javax.mail.Message" %>
<%@ page import="javax.mail.Session" %>
<%@ page import="javax.mail.Transport" %>
<%@ page import="javax.mail.internet.InternetAddress" %>
<%@ page import="javax.mail.internet.MimeMessage" %>
<%@ page import="com.google.apphosting.api.ApiProxy" %>
<%
if (request.getMethod().equals("POST")) {
    String text = request.getParameter("message");
    String to = request.getParameter("email");
    String toName = request.getParameter("name");
    String from = ApiProxy.getCurrentEnvironment().getAppId() +
        "@appspotmail.com";
    Properties props = new Properties();
    Session s = Session.getDefaultInstance(props, null);
    try {
        Message mail = new MimeMessage(s);
        mail.setFrom(new InternetAddress(from, "Não Responder"));
        mail.addRecipient(Message.RecipientType.TO,
            new InternetAddress(to, toName));
        mail.setSubject("Obrigado pelo seu contato");
        mail.setText(text);
        Transport.send(mail);
        request.setAttribute("sent", true);
    } catch (Exception e) {
        request.setAttribute("error", e.getMessage());
    }
}
%>

O código acima utiliza o pacote Java Mail (javax.mail) para o envio da mensagem. O App Engine disponibiliza o envio de e-mails com o remetente [email protected], que é pré-configurado para o Java Mail. Também é possível utilizar e-mails adicionados ao projeto como remetentes das mensagens enviadas, permitindo customizar a experiência com o usuário. Outra opção é o uso de serviços externos.

Observação: No exemplo acima, estamos mixando o código java dentro da página JSP. O ideal em um caso como este seria utilizar um Servlet para o tratamento do POST do formulário, e utilizar o RequestDispatcher à partir do Servlet para exibir o resultado do envio.

Nós definimos alguns atributos na requisição acima:

  • sent é definido para true quando a mensagem é enviada com sucesso.
  • error é definido com o texto do erro caso haja alguma falha.

Vamos atualizar nosso código para que o template acima exiba a mensagem logo antes do formulário, indicando se houve sucesso ou algum erro. Para isso, localize a tag <form> na página de contato e inclua o código abaixo logo antes dela:

<% if (request.getAttribute("sent") != null) { %>
<div class="alert alert-success">
    Email enviado com sucesso!
</div>
<% } else if (request.getAttribute("error") != null) { %>
<div class="alert alert-danger">
    Houve um erro ao enviar seu e-mail:
    <%= request.getAttribute("error") %>
</div>
<% } %>

Para concluir, inclua os nomes dos atributos nas tags input, para os campos name, email e message, e vamos definir o método do formulário para POST:

<form method="post" ....

Testando a página de contato

Agora que a nossa página de contato está implementada, vamos atualizar o link de contato na página principal, e testar o funcionamento de nosso website:

  1. Navegue pelo link de contato do site até a página de contato.
  2. Preencha o formulário de contato com seu endereço de e-mail, e uma mensagem de testes.
  3. Clique no botão enviar, e observe se no terminal de comandos onde o servidor está em execução, aparecerá um log de envio de e-mail; O servidor de desenvolvimento não envia efetivamente os e-mails.

Com isso concluímos o nosso website, que está pronto para ser publicado e testado no ambiente de produção.