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.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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:

01
02
03
04
05
06
07
08
09
10
11
<!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.

Sobre: Thiago Galbiatti Vespa

Thiago Galbiatti Vespa é mestre em Ciências da Computação e Matemática Computacional pela USP e bacharel em Ciências da Computação pela UNESP. Coordenador de projetos do JavaNoroeste, membro do JCP (Java Community Process), consultor Oracle, arquiteto de software de empresas de médio e grande porte, palestrante de vários eventos e colaborador de projetos open source. Possui as certificações: Oracle Certified Master, Java EE 5 Enterprise Architect – Step 1, 2 and 3; Oracle WebCenter Portal 11g Certified Implementation Specialist; Oracle Service Oriented Architecture Infrastructure Implementation Certified Expert; Oracle Certified Professional, Java EE 5 Web Services Developer; Oracle Certified Expert, NetBeans Integrated Development Environment 6.1 Programmer; Oracle Certified Professional, Java Programmer; Oracle Certified Associate, Java SE 5/SE 6