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.
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).
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:
Indicar el Content-Type de la respuesta como una imagen PNG
Crear el Frame y dibujar la imagen sobre el objeto Graphics
Obtener el OutputStream de la respuesta y volcar la imagen utilizando un JimiWriter.
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:
Indicamos el Content-Type de la respuesta como una imagen PNG
En este caso creamos una BufferedImage y dibujamos con su objeto Graphics2D
Obtenemos el OutputStream de la respuesta y volcamos la imagen utilizando el codificador, en este caso un JPEGImageEncoder.
NOTA: al utilizar el paquete com.sun, no se garantiza la portabilidad de este sistema de generación de imágenes.
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.