3. Conceptos avanzados

 

Veremos en este tema algunos aspectos avanzados sobre el trabajo con servlets, como son la generación dinámica de imágenes con servlets, la gestión de un pool de conexiones combinando servlets con JDBC, y la seguridad en servlets y aplicaciones Web.

3.1. Generación de imágenes con servlets

En ocasiones se necesita representar cierto tipo de información (datos numéricos, por ejemplo) con alguna imagen (una gráfica, etc). Si los datos son fijos podríamos construir la imagen a priori y mostrarla luego directamente, pero si los datos pueden cambiar con cierta frecuencia (como por ejemplo las visitas mensuales o anuales a una página), o la cantidad de datos es tan grande que hacerlo a mano puede resultar muy pesado, entonces es conveniente construir dinámicamente estas imágenes.

A la hora de manipular imágenes, debemos tener en cuenta el formato de las mismas. En sistemas Web el formato más común es GIF, aunque si queremos escribir en formato GIF, debemos tener en cuenta que su formato de compresión está protegido por una patente. Así que podemos decantarnos por otros formatos soportados, como son JPEG o PNG. 

Para generar estas imágenes dinámicas se siguen básicamente dos pasos:

El problema es que la API de Java no ofrece muchas facilidades para realizar estas tareas, aunque sí pueden utilizarse algunas de sus librerías para ello. Dependiendo de la versión de Java que se esté manejando, podremos optar por unas posibilidades u otras.

Veremos a continuación cómo construir un círculo azul, utilizando Java 1.1 por un lado, y utilizando luego versiones posteriores (algunos servidores y/o navegadores no incorporan aún versiones posteriores a Java 1.1, por motivos de compatibilidad con el plug-in).

3.1.1. Generación de imágenes con Java 1.1

Para leer/escribir imágenes en Java 1.1 Sun ofrece una librería llamada Jimi, dentro del paquete com.sun. Así, para producir una imagen PNG utilizando esta librería, los pasos a dar son:

Aquí vemos el código de un servlet que crea el círculo utilizando esta técnica, y lo sirve como resultado:

import java.io.*;
import java.awt.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.sun.jimi.core.*;

public class ServletImagenes11 extends HttpServlet
{
	// Metodo para GET
	
	public void doGet(HttpServletRequest request, 
			  HttpServletResponse response) 
	throws ServletException, IOException
	{
		response.setContentType("image/png");
		
		// Crear el frame
		
		Frame f = new Frame();
		f.setVisible(true);
		Image img = f.createImage(150, 150);
		Graphics g = img.getGraphics();
		f.setVisible(false);

		// Dibujar la imagen

		g.setColor(Color.blue);
		g.fillOval(0, 0, 100, 100);
		
		// Crear el JimiWriter para volcar la imagen 
		// al OutputStream que se pida
		
		try
		{
			OutputStream salida = 
				response.getOutputStream();
			JimiWriter writer = 
				Jimi.createJimiWriter(
					"image/png", salida);
			writer.setSource(img);
			writer.putImage(salida);
		} catch (JimiException e) {}
	}
}

El paquete com.sun.jimi.core contiene las clases de Jimi para generar imágenes. Lo que hacemos es:

3.1.2. Generación de imágenes con Java 1.2

Para generar imágenes con versiones posteriores de Java 1.1, se pueden utilizar codificadores específicos. Por ejemplo, para generar imágenes JPEG se emplea la clase com.sun.image.codec.jpeg.JPEGImageEncoder. Los pasos a dar son:

Aquí vemos el código de un servlet que crea el círculo utilizando esta técnica, y lo sirve como resultado:

import java.io.*;
import java.awt.*;
import java.awt.image.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.sun.image.codec.jpeg.*;

public class ServletImagenes12 extends HttpServlet
{
	// Metodo para GET
	
	public void doGet(HttpServletRequest request, 
			  HttpServletResponse response) 
	throws ServletException, IOException
	{
		response.setContentType("image/jpeg");
				
		// Crear la imagen
		
		BufferedImage img = 
		   new BufferedImage(150, 150, 
			BufferedImage.TYPE_BYTE_INDEXED);
		Graphics2D g = img.createGraphics();

		// Dibujar

		g.setColor(Color.blue);
		g.fillOval(0, 0, 100, 100);
		
		// Crear el Codificador para volcar la imagen 
		// al OutputStream que se pida
		
		try
		{
			OutputStream salida = 
			    response.getOutputStream();
			JPEGImageEncoder encoder = 
			    JPEGCodec.createJPEGEncoder(salida);
			encoder.encode(img);
		} catch (Exception e) {}
	}
}

Igual que en el caso anterior:

NOTA: al utilizar el paquete com.sun, no se garantiza la portabilidad de este sistema de generación de imágenes.

3.1.3. Ejemplos

Tenéis un WAR con los dos servlets propuestos. Copiadlo en el directorio webapps de Tomcat, reiniciad el servidor y probad los servlets:

http://localhost:8080/ejemploimagenes/servlet/ServletImagenes11
http://localhost:8080/ejemploimagenes/servlet/ServletImagenes12

Notar que en los dos métodos vistos (para Java 1.1 y para Java 1.2) se genera la imagen sola. Podemos generar la imagen junto con otro contenido en una página HTML, sin más que haciendo que el OutputStream sea un fichero (PNG o JPG, según el ejemplo) en lugar del HttpServletResponse, y luego escribiendo un tag <img> que cargue dicho fichero:

...
FileOutputStream fichero = new FileOutputStream("imagen.png");
crearImagen(fichero);
PrintWriter out = response.getWriter();
out.println ("<img src=\"imagen.png\">");
...

donde crearImagen() haría los mismos pasos que se han visto en el método doGet(), volcando la imagen creada a la salida fichero.