Lo que necesitamos:
- eclipse (con wtp para mayor comodidad)
- apache tomcat 6 (o algun otro contenedor de servlets)
- commons-fileupload-1.2.jar
- commons-io-1.3.1.jar
- mysql-connector-java-5.1.5-bin.jar (Este driver depende de su motor de base de datos)
- MySql 5.0.67 (Esta es la bd que uso, podrían ocupar cualquier otra que soporte datos BLOB)
- Opcionalmente: log4-1.2.11.jar, jstl.jar, standar.jar (las ultimas dos vienen en los ejemplos de apache-tomcat 6, en versiones anteriores se encuentran en el directorio lib de tomcat)
No es absolutamente necesario usar eclipse, podrían realizar el proyecto con algún otro ide o sin usar algún ide.
Para insertar la imagen realice el siguiente método que pertenece a mi DAO:
public void insertaImagenProducto(int idProducto,
InputStream inps, long size) {
PreparedStatement ps=null;
try {
ps = con.prepareStatement(
"UPDATE PRODUCTOS SET IMAGEN = ? WHERE" +
" PRODUCTO_ID = ?");
ps.setBinaryStream(1, inps, (int)size);
ps.setInt(2, idProducto);
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
En el método de insertaImagen, únicamente recibo un InputStream del cual se leerán los bytes que se insertaran en el campo BLOB, tambien se recibe el tamaño del InputStream o el numero de bytes que contiene y finalmente se llama al método setBinaryStream del objeto preparedStatment con el cual se inserta la imagen en la bd
Para recuperar un dato BLOB de la bd se realiza lo siguiente:
public byte[] obtenImagenProducto(int idProducto) {
ResultSet rst = null;
PreparedStatement pstm = null;
byte[] buffer = null;
try {
logger.info("Datos producto id " +idProducto);
String sql = "select imagen from
productos where producto_id = ?";
pstm = con.prepareStatement(sql);
pstm.setInt(1, idProducto);
rst = pstm.executeQuery();
while (rst.next()){
Blob bin = rst.getBlob("imagen");
if (bin != null) {
InputStream inStream = bin.getBinaryStream();
int size = (int) bin.length();
System.out.println(" El tamaño en bytes " + size);
buffer = new byte[size];
int length = -1;
int k = 0;
try {
inStream.read(buffer, 0, size);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
} catch (SQLException ex) {
logger.error("ERROR " + ex);
return null;
} finally {
/*
rst.close();
stm.close();
*/
rst = null;
pstm = null;
}
return buffer;
}
Este método obtiene un dato de tipo BLOB, si el dato es diferente de nulo entonces se crea un objeto de tipo InputStream con el cual se leerán los bytes del dato blob, se crea un arreglo de bytes de acuerdo al tamaño del blob y posteriormente se leen, una vez leídos los bytes estos simplemente se retornan en el arreglo creado, en la siguiente capa se reciben estos bytes y se envian al navegador.
Lo anterior es la parte que pertenece al modelo, ahora vamos con la parte correspondiente a la vista, en esta parte tenemos un jsp que contiene el siguiente formulario :
<form name="myform" action="./ServletProductoImagen"
method="post" enctype="multipart/form-data">
<input type="hidden" value="${param.idProducto}" name="idProducto">
Selecciona la Image:
<input type="file" name="myimage">
<input type="submit" name="Aceptar" value="Submit your files">
<form>
Bien con este formulario escogeremos el archivo que se agregara a la base de datos,
yo le paso un parámetro, el idProducto con este sabre en que registro insertar la imagen,
yo le paso un parámetro, el idProducto con este sabre en que registro insertar la imagen,
Ahora veamos el servlet que inserta la imagen, en el método post :
// first check if the upload request
//coming in is a multipart request
//Revisa si la peticion es multipart
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
// Create a factory for disk-based file items
//Esto es parte de la lib de commons-fileupload
//y es un objeto para generar archivos temporales
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
//Aqui crea un objeto para manejar la peticion
//que llega con un archivo
ServletFileUpload upload = new ServletFileUpload(factory);
// parse this request by the handler
// this gives us a list of items from the request
List items = null;
try {
//Se obtienen los items de la forma
//es decir obtenemos los parametros de la forma
items = upload.parseRequest(request);
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String idProducto = "";
Iterator itr = items.iterator();
while(itr.hasNext()) {
//recorremos los items en busca del id
//para realizar el insert
FileItem item = (FileItem) itr.next();
if(item.isFormField()) {
// get the name of the field
String fieldName = item.getFieldName();
if(fieldName.equals("idProducto"))
idProducto = item.getString();
}
logger.info("ID Producto" + idProducto);
}
itr = items.iterator();
//ahora lo recorremos para obtener el archivo que se
//envio en la forma
while(itr.hasNext()) {
FileItem item = (FileItem) itr.next();
// check if the current item is a form field or
//an uploaded file
if(! item.isFormField() ){
// the item must be an uploaded file save it to disk.
// Note that there
// seems to be a bug in item.getName() as it
//returns the full path on
// the client's machine for the uploaded file name,
// instead of the file
// name only. To overcome that, I have used a
// workaround using
// fullFile.getName().
//Aqui es donde se obtiene el nombre del archivo, esto podriamos
//usarlo si queremos gurdar el nombre o guardar el archivo en
//alguno de nuestros directorios.
//File fullFile = new File(item.getName());
//File savedFile = new File(fullFile.getName());
try {
//Este metodo comentado escribe el archivo en nuestro
//sistema de archivos con una ruta adecuada
//item.write(savedFile);
//pero lo que nos interesa es gurdar la imagen en la bd, asi
//que invocamos a nuestro dao y le pasmos los valores
//necesarios y es todo
daoProductos.insertaImagenProducto(
Integer.parseInt(idProducto),
item.getInputStream(),
item.getSize());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Archivo guardado");
}
}
RequestDispatcher r =
request.getRequestDispatcher("./index.jsp");
r.forward(request, response);
}
Aqui es donde hacemos uso de el jar commons-fileupload, con este obtenemos
el archivo que se envio al servlet a travez de la forma, revisamos por los
parametros que se encuentran en la forma, el id para saber el registro en
donde se insertara la imagen, posteriormente obtenemos un inputStream con los
bytes de la imagen y el numero de bytes. Y lo enviamos a nuestro dao para que
realize el insert en la bd.
Para terminar, para mostrar la imagen en nuestro jsp entonces invocamos al metodo
doGet de el servlet en el cual tenemos lo siguiente:
String idProducto = request.getParameter("idProducto");Aqui le enviamos el id del registro del cual se obtendra la imagen despues colocamos el contentype del response como image, invocamos anuestro dao que nos devolvera los bytes, obtenemos el ServletOutputStream para enviar los bytes de la imagen, en nuestro jsp simplemente hariamos:
System.out.println(" El id del idProducto " + idProducto);
if(idProducto!=null && !idProducto.equals("")){
int idProd = Integer.parseInt(idProducto);
response.setContentType("image/gif");
byte [] imag = this.obtieneProducto(idProd);
if(imag != null) {
ServletOutputStream out = response.getOutputStream();
out.write(imag);
}
}
<img src="./ServletProductoImagen?idProducto=${producto.idProducto}"Espero colocar el proyecto de eclipse para que puedan descargarlo solo debo ver como o donde
alt="${producto.nombre}" height="150" width="150" >
18 comentarios:
Jovenes javeros, muy bien su post, en base a lo que uno aprende pues esta es una buena solucion al problema de subir imágenes a una BD(mysql,sql,oracle), claro con su respectivo driver, hay algunos que tienen problemas con los drivers, o con los queries o hasta con el método UpLoad para obtener el archivo jeje :$ es bueno explicar las distintas formas en una aplicación web(Struts, servlets, etc), pero también es bueno que expliquemos el COMO leer el archivo y mandarlo a la BD, muy buen post, deberían hacer unos dando una explicación o ejemplo en struts y en una aplicación de escritorio.
Como nota, hay que tener cuidado porque muchas veces los campos BLOB están limitados en la implementación, en una aplicación tuve un error de que el campo BLOB estaba limitado a 4KB por lo que con archivos pequeños funcionaba bien, pero en otros los cortaba, en ese caso usé LONGBLOB.
amigo me parece muy buena tu contribucion pero me pareceria aun mejor si aunque sea dieran los jar para poder descaragarlos
Para los que quieren descargar los archivos .jar necesarios para realizar esta operacion les recomiendo esta pagina :
http://www.jarfinder.com/index.php/
Aki al hacer click en la pestaña jar podran buscar los jares necesarios para este proyecto.Salu2
Y por ultimo, te agradeceria mucho si me dieras el proyecto a mi correo : luismiguel12311@hotmail.com
uaooooo me sirvio de mucho su idea me salio todo perfecto, saludos
mi correo es garoalex_85@live.com.mx
para lo que les pueda ayudar...
hola muy buen aporte yo estaba buscando hace tiempo esto, agredeceria si me envias el proyecto a mi correo porfa luis55_2@hotmail.com, gracias de antemano
Genial. Me ha servido 100%.
Llevaba mucho tiempo buscando algo así de simple y de efectivo. GRACIAS desde Sevilla (España).
Que tal gente? soy nuevo en el campo de la programación en java y respecto a este post quisiera saber si puede funcionar también para subir a la BD archivos que no sean necesariamente imágenes, sino archivos de texto o pdf. Espero me respondan. Gracias
Que tal, si puedes usarlo, los datos se guardan en binario, solo que para mostrarlos harias algunas cosas diferentes
Hola amigo me puedes enviar el proyecto te agradeceria mucho.
mcrewjeiga@hotmail.com
Hola hermano excelente, me parece totalmente estupendo justo lo que necesitaba para mejorar mi proyecto. Ahora por favor serias tan amable de enviarme el proyecto completo para analizarlo. a hack10.5@hotmail.com
hola que tal muy buen aporte , disucpa me preguntaba si me podias enviar el proyecto a mi correo es chivasjm_val@hotmail.com te lo agradeceria mucho
hola que tal? muy buen aporte , disculpa me podrias enviar el proyecto a mi correo es jjadb@hotmail.com
Gracias por adelantado ;)
Amigo me parece muy interesante tu ejemplo, pero tengo un problema al momento de emplearlo en mi proyecto me genera varios errores, me preguntaba si serias tan gentil de compartirme el código fuente muchas gracias de antemano.
mi correo es jj.garciatc@gmail.com
Excelente explicación.
¿Por que piden que les envien el codigo fuente al correo si ya esta detallado en el post?.
Publicar un comentario