Guardando y mostrando imágenes desde bases de datos con JSP
Vamos a aprender a guardar imágenes en una base de datos (Oracle, MySQL, SQLServer, cualquiera a la que Java pueda acceder, es decir, casi todas) y a mostrarlas a continuación, utilizando sencillas páginas JSP.
Formulario y ejemplo de invocación de imagen
En éste código definiremos el formulario (ojo a la declaración, ha de ser multipart) y además mostraremos una imagen desde la BD; ambos elementos usarán los arhivos que definiremos a continuación:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-15">
<title>Cargador de imágenes desde BD</title>
</head>
<body style="margin: 20px;">
<h1>Cargador de imágenes desde BD</h1>
<hr/>
<h2>Subir una imagen a la BD</h2>
<form enctype='multipart/form-data' action="subir.jsp" method="post">
Elige la imagen (PNG) a subir: <input type="file" name="imagen" /><br/>
<input type="submit" value="Subir archivo" />
</form>
<h2>Imagen desde BD</h2>
<img src="img.jsp?id=1" />
</body>
</html>
Guardado de la imagen en BD
En éste JSP veremos cómo extraer los datos de la imagen que acabamos de subir y como codificarlos a Base64. Ésta cadena codificada será la que guardemos en BD, como si de otra cadena cualquiera se tratase:
<%@page import="sun.misc.BASE64Encoder"%>
<%@page import="java.io.DataInputStream"%>
<%@page contentType="text/html" pageEncoding="ISO-8859-15"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-15">
<title>Cargador de imágenes desde BD</title>
</head>
<body style="margin: 20px;">
<h1>Cargador de imágenes desde BD</h1>
<hr/>
<h2>Subiendo imagen...</h2>
<%
// Es un formulario multipart, cogeremos cada una de esas partes
String contentType = request.getContentType();
if ((contentType != null) && (contentType.indexOf("multipart/form-data") >= 0))
{
// Cogemos el flujo de entrada
DataInputStream in = new DataInputStream(request.getInputStream());
// Empezamos a leer
int longitud = request.getContentLength();
byte dataBytes[] = new byte[longitud];
int byteLeido = 0;
int numBytesLeidos = 0;
while (numBytesLeidos < longitud)
{
byteLeido = in.read(dataBytes, numBytesLeidos, longitud);
numBytesLeidos += byteLeido;
}
// Extraemos la porción con el archivo añadido
String archivo = new String(dataBytes);
// Buscamos la posición de los datos
int lastIndex = contentType.lastIndexOf("=");
String boundary = contentType.substring(lastIndex + 1, contentType.length());
int pos;
pos = archivo.indexOf("filename=\"");
pos = archivo.indexOf("\n", pos) + 1;
pos = archivo.indexOf("\n", pos) + 1;
pos = archivo.indexOf("\n", pos) + 1;
int boundaryLocation = archivo.indexOf(boundary, pos) - 4;
int startPos = ((archivo.substring(0, pos)).getBytes()).length;
int endPos = ((archivo.substring(0, boundaryLocation)).getBytes()).length;
// Copiamos los datos en un array
byte[] datosArchivo = new byte[(endPos - startPos)];
System.arraycopy(dataBytes, startPos, datosArchivo, 0, (endPos - startPos));
// Codificamos a Base64
BASE64Encoder e = new BASE64Encoder();
String datos = e.encodeBuffer(datosArchivo);
// Guardamos en la BD
guardarEnBaseDeDatos(datos);
}
%>
Redirigiendo...
<script language="javascript">
location.href="index.jsp";
</script>
</body>
</html>
Lectura de la imagen desde BD
Una vez guardada, para invocarla bastará con leer ésa cadena desde la base de datos y mostrarla como salida de un script JSP, estableciendo el tipo MIME del contenido al de la imagen que hayamos guardado, para que el navegador la interprete correctamente como imagen:
<%@page contentType="image/png" %><%@page import="sun.misc.BASE64Decoder" %><%
// Cargamos desde la BD
String datos = cargarDesdeLaBaseDeDatos(request.getParameter("id"));
// Decodificamos
BASE64Decoder d = new BASE64Decoder();
byte[] datosImagen = d.decodeBuffer(datos);
// Mostramos como salida del JSP
%><%= datosImagen %>
¿Alguien conoce una forma más sencilla de hacerlo? Todo comentario será bienvenido
¡Happy coding!
¡Suscribete al feed RSS!