Gerar imagens dinâmicas com servlets

HTTP Servlets tem utilidade mais interessante do que apenas Front Controllers e gerar código HTML. Um dos recursos mais bacanas é a possibilidade de gerar conteúdo binário em tempo de execução. Nesse post demonstrarei como desenhar uma imagem dinâmica utilizando Servlets. A idéia veio da necessidade do Cássio em extrair páginas de PDF e exibir como imagens em uma aplicação Web.

Vamos criar uma Servlet onde o usuário poderá realizar uma requisição via GET da URL “imagem.png” passando um parâmetro “texto” e a Servlet irá retornar uma imagem com uma bolinha e o texto digitado.

Estou utilizando Servlet 3.0, mas o código do método get pode ser utilizado em qualquer outra versão de Servlets sem necessidade de alteração.

package br.com.thiagovespa.samples.imagem;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Gera uma imagem com um texto passado por parâmetro
 *
 * @author Thiago Galbiatti Vespa
 */
@WebServlet("/imagem.png")
public class ImagemServlet extends HttpServlet {
	private static final long serialVersionUID = 201011231103L;
	public ImagemServlet() {
		super();
	}
	@Override
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// A imagem é um png - Poderia ser qualquer outro tipo
		response.setContentType("image/png");
		// Recupera o parâmetro
		String text = request.getParameter("texto");
		// Cria uma imagem de tamanho 500x50
		BufferedImage image = new BufferedImage(500, 50,
				BufferedImage.TYPE_INT_ARGB);
		// Cria o canvas pra desenho
		Graphics2D canvas = image.createGraphics();
		canvas.setColor(Color.BLUE);
		// Desenha um círculo azul
		canvas.fillOval(10, 10, 10, 10);
		canvas.setColor(Color.RED);
		canvas.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 14));
		// Desenha o texto em vermelho
		canvas.drawString(text != null ? text : "Nenhum texto informado!", 25,
				20);
		OutputStream out = null;
		try {
			out = response.getOutputStream();
			// Escreve a imagem no outputstream da response no formato png
			ImageIO.write(image, "PNG", out);
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}
}

Fiz vários comentários no código para facilitar a compreensão de quem está começando e para eu não precisar explicar linha a linha o que o código está fazendo :) . O código importante  para gerar qualquer conteúdo binário é o que está destacado na linha 35, que seta o mime-type correto para a servlet exibir e o da linha 56 que recupera o OutputStream (binário) para escrever algum conteúdo nele.

Para utilizar o mime-type correto pro seu tipo de conteúdo, você pode utilizar a tabela da W3School disponível nesse link: http://www.w3schools.com/media/media_mimeref.asp

Agora é só fazer o deploy de um projeto com essa Servlet e acessá-la passando um parâmetro. O resultado você pode ver na imagem abaixo:

imagem.png (500×50)

imagem.png (500×50)

Para exibir dentro de uma página HTML é só referenciar o endereço da Servlet no atributo src da tag img. Por exemplo:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Exemplo imagem</title>
</head>
<body>
Olha minha imagem a&iacute; em baixo<br/>
<img src="imagem.png?texto=Imagem gerada!"/>
</body>
</html>

O browser irá exibir o conteúdo da imagem gerada dinâmicamente:

Exemplo imagem

Exemplo imagem

Agora é só programar a Servlet para gerar o que você quiser!.

Esse conceito é utilizado para geração de CAPTCHAs, PDF, XLS, e outros arquivos binários dinamicamente.

Instalação do Tomcat 7 – Servlet 3.0, JSP 2.2 e EL 2.2.

O Tomcat é um container de Servlets da Apache Software Foundation. Em linhas gerais ele é um servidor HTTP que executa JSP e Servlets.

Ele possui alguns componentes:

  • Catalina: Container de Servlets.
  • Coyote: Conector HTTP, responsável por receber requisições HTTP e redirecionar.
  • Jasper: Engine JSP do Tomcat, ela converte e compila o JSP em uma Servlet para ser gerenciada pelo Catalina.

Nesse post vamos instalar o Tomcat 7 que possui suporte as novas especificações: Servlet 3.0, JSP 2.2 e EL 2.2.

Para baixar o Tomcat 7, temos que acessar: http://tomcat.apache.org/download-70.cgi#Binary_Distributions

Após o download, descompactar em uma pasta de sua preferência ou executar a instalação se for windows e você baixou o installer.

Para iniciar, executar o arquivo: $TOMCAT_HOME/bin/startup.sh (ou .bat se for Windows).

Se tudo estiver ok, no log $TOMCAT_HOME/logs/catalina.out deve aparecer o seguinte:

Aug 30, 2010 11:08:21 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory docs
Aug 30, 2010 11:08:21 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory host-manager
Aug 30, 2010 11:08:21 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Aug 30, 2010 11:08:21 AM org.apache.coyote.ajp.AjpProtocol start
INFO: Starting Coyote AJP/1.3 on ajp-8009
Aug 30, 2010 11:08:21 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 489 ms

Para parar, executar o arquivo: $TOMCAT_HOME/bin/shutdown.sh (ou .bat se for Windows).

Em um próximo post coloco como criar um projeto utilizando os recursos do Servlet 3.0. Pra quem quiser já ir vendo sobre o assunto, tem uma excelente introdução em: http://today.java.net/pub/a/today/2008/10/14/introduction-to-servlet-3.html