Seleccionar página

Vamos a ir poco a poco centrándonos en algunas partes concretas del proyecto que presente de la tienda online y así veremos en detalle determinadas partes. Hoy nos vamos a centrar en ofrecer la posibilidad de que el cliente de nuestra web pueda subir imágenes a nuestro servidor web de una manera muy sencilla

Antes de la especificación 3.0 de los Servlets esta tarea se tenía que  hacer usando las librerías de Apache Commons y se convertía en una tarea más larga y menos clara; desde la nueva especificación no es necesario usar ninguna librería externa dado que nos da esta posibilidad de serie y de una manera muy sencilla. Pues bien, comencemos.

El formulario

Lo primero que hay que hacer es una pequeña modificación en el formulario donde se quiera subir la imagen, puesto que ahora los datos no se van a enviar en modo texto sino como un flujo binario, y teniendo en cuenta esto último el verbo HTTP usado será POST y nunca GET; de manera que la cabecera de nuestro formulario tendra una forma como la que os muestro.

Una vez que ya tenemos la estructura del formulario HTML, ya podemos añadir los campos que queramos al formulario al igual que lo hacemos normalmente, sabiendo que el campo para seleccionar la imagen sera de tipo file. Una vez hecho nos quedaría algo como lo que sigue.

Procesando el formulario

Una vez que ya tenemos el formulario HTML preparado ya estaríamos en condiciones de pasar a la parte de servidor para procesar este formulario que hemos creado; es decir, crear el Servlet encargado de procesar este formulario; que veremos que se procesa de una forma algo distinta a como estamos acostumbrados; principalmente debido a que ahora no hemos recibido texto sino un flujo de datos y de ahí tendremos que obtener el texto normal y la fotografía. En el formulario he puesto tres tipos de campos para que veamos como procesar cada uno de ellos (texto, archivo, textarea).

En primer lugar el Servlet encargado de procesar el formulario deberá llevar la anotación @MultipartConfig. Y ahora puede haber varias preguntas clave.

  • ¿Cómo se si se ha enviado la imagen o no? (el usuario pudo no poner la imagen). Sencillo, si el Part (nombre que se le da a un campo en un formulario de este tipo) ocupa cero bits.
  • ¿Cómo se si el archivo que se ha seleccionado es una imagen? Hay un método para saber el tipo de archivo subido. Si contiene la cadena image sabremos que es una imagen (image/jpeg, etc…)
  • ¿Cómo guardamos la imagen en disco? Tendremos que obtener el InputStream del Part.
  • ¿Cómo obtenemos los campos que son de tipo texto, ahora no recibo texto? Ahora veremos que hay una manera sencilla de hacerlo. Os enseñaré los métodos de la clase estática Tools.

Ahora os muestro el código del Servlet completo, he puesto algunos comentarios en el mismo. Está basado en uno de los Servlets de tienda online, he quitado bastante código para mostrar prácticamente solo lo referente al tema que nos concierne ahora en concreto, obviamente entendiendo lo fundamental podemos modificarlo para que cumpla con la función que cada uno desee. En el código veremos que se resaltan las líneas fundamentales que responden a cada una de las preguntas que he planteado en el párrafo anterior. Por supuesto el Servlet estará dado de alta en el descriptor de despliegue y atendiendo peticiones en la ruta a la que se envía el formulario HTML.

Resumiendo, lo primero que hace el servlet es comprobar que se reciben los parámetros correctos y no menos, si la validación ha sido correcta se obtienen los campos de texto como veremos ahora. Posteriormente comprobamos si hay archivo o no, y en caso de que lo haya comprobamos que es una imagen y que el tamaño no exceda de 8 Mb, posteriormente se guarda en disco el archivo. Si queréis obtener más información sobre el archivo os animo a que investiguéis los métodos del objeto Part. Es enviado un error 404 para una petición GET que llegue a este servlet debido a que no tendría porque accederse por dicho verbo HTTP (no hay ninguna razón para hacerlo) y podríamos evitarnos así posibles problemas, evitamos que se “hagan experimentos” con nuestra aplicación web.

Los atributos que yo añado a la petición son usados para dar el mensaje correspondiente en la jsp a la que se redirige, por lo tanto vosotros hacer caso solo al texto de los mensajes.

Y ahora nos falta ya por concretar como obtener los campos de texto y como guardar la imagen en disco que tal como aparece en el Servlet aparece simplificado al aparecer en una única línea, pero claro, hay que ver lo que hace esa línea.

Para el caso del texto veremos que podemos obtener un InputStream del Part del formulario y podemos leerlo por ejemplo con la clase Scanner de Java. La única diferencia entre obtener el texto de un campo de texto y un textarea será que tenemos que mantener los saltos de línea para el segundo como veremos ahora. Mientras que en un campo de texto solo habrá una línea. Otro apunte importante sería especificar la codificación para evitar errores con caracteres como tildes, eñes o similares. Por último decir que observéis como se abren y se cierran los objetos de tipo Scanner asegurándonos de que se cierren siempre ocurra o error o no.

Bueno, y ahora ya solo nos faltaría ver como guardar la imagen en disco, como hemos dicho obteniendo el InputStream del Part del formulario (que ya lo obtuvimos en el Servlet y se lo pasamos ahora a este método estático) y también asegurándonos de cerrar los flujos de datos en todos los casos de error y de éxito.

Hasta aquí creo que no se me queda ningún aspecto por cubrir, únicamente añadir alguna anotación. Comentar que sería interesante para administrar las imágenes guardar sus nombres en una base de datos haciéndolas corresponder con productos por ejemplo en el caso de una tienda. Y aspectos a corregir de mi modo de hacerlo en el proyecto de la tienda sería guardar las imágenes con extensión, puede ser que no todos los navegadores muestren la imagen correctamente, también sería interesante guardar las imágenes con nombres normales y no con códigos, esto último más que nada para el SEO (Search Engine Optimization), debido a que con nombres normales las imágenes se indexarán mejor en los buscadores.

Ahora ya si que he dicho todo lo que tenía que decir y se han cubierto todos los aspectos sobre el tema. Espero que os sea de utilidad esta guía y como siempre digo estoy abierto a dudas sugerencias o lo que os haga falta.

Pin It on Pinterest

Share This