¿Cómo recuperar y visualizar imágenes desde una base de datos en una página JSP?

¿Cómo puedo recuperar y mostrar imágenes de una base de datos en una página JSP?

Veamos en pasos lo que debería suceder:

  • JSP es básicamente una tecnología de visualización que se supone que genera resultados en HTML.
  • Para mostrar una imagen en HTML, necesita el elemento HTML .
  • Para que encuentre una imagen, debe especificar su atributo src .
  • El atributo src necesita apuntar a una URL http:// válida y, por lo tanto, no a un archivo de ruta del sistema de archivos de disco local file:// ya que eso nunca funcionaría cuando el servidor y el cliente se ejecutan en máquinas físicamente diferentes.
  • La URL de la imagen debe tener el identificador de imagen en la ruta de solicitud (p. Ej., http://example.com/context/images/foo.png ) o como parámetro de solicitud (p. Ej., http://example.com/context/images?id=1 ).
  • En el mundo de JSP / Servlet, puede permitir que un servlet escuche en un determinado patrón de URL como /images/* , para que pueda ejecutar código Java en URL específicas.
  • Las imágenes son datos binarios y deben obtenerse como un byte[] o InputStream de la base de datos, la API de JDBC ofrece ResultSet#getBytes() y ResultSet#getBinaryStream() para esto, y la API de JPA ofrece @Lob para esto.
  • En el Servlet, puede escribir este byte[] o InputStream en OutputStream de la respuesta, la forma habitual de Java IO .
  • El lado del cliente necesita instrucciones para que los datos se manejen como una imagen, por lo que al menos también se debe establecer el encabezado de respuesta de Content-Type . Puede obtener el correcto a través de ServletContext#getMimeType() basado en la extensión de archivo de imagen que puede ampliar y / o sobrescribir a través de en web.xml .

Eso debería ser. Casi escribe el código en sí mismo. Comencemos con HTML (en JSP ):

    

Si es necesario, también puede establecer dinámicamente src con EL mientras itera usando JSTL :

    

A continuación, defina / cree un servlet que escuche en las solicitudes GET en el patrón de URL de /images/* , el ejemplo siguiente utiliza el JDBC estándar vainilla para el trabajo:

 @WebServlet("/images/*") public class ImageServlet extends HttpServlet { // content=blob, name=varchar(255) UNIQUE. private static final String SQL_FIND = "SELECT content FROM Image WHERE name = ?"; @Resource(name="jdbc/yourDB") // For Tomcat, define as  in context.xml and declare as  in web.xml. private DataSource dataSource; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String imageName = request.getPathInfo().substring(1); // Returns "foo.png". try (Connection connection = dataSource.getConnection(); PreparedStatement statement = connection.prepareStatement(SQL_FIND)) { statement.setString(1, imageName); try (ResultSet resultSet = statement.executeQuery()) { if (resultSet.next()) { byte[] content = resultSet.getBytes("content"); response.setContentType(getServletContext().getMimeType(imageName)); response.setContentLength(content.length); response.getOutputStream().write(content); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404. } } } catch (SQLException e) { throw new ServletException("Something failed at SQL/DB level.", e); } } } 

Eso es. En caso de que se preocupe por HEAD y los encabezados de caché y responda adecuadamente en esas solicitudes, use esta plantilla abstracta para el servlet de recursos estáticos .

Ver también:

  • ¿Cómo debo conectarme a la base de datos / fuente de datos JDBC en una aplicación basada en servlet?
  • ¿Cómo subir una imagen y guardarla en la base de datos?
  • La forma más simple de servir datos estáticos desde fuera del servidor de aplicaciones en una aplicación web Java

Sugiero que aborden eso como dos problemas. Hay varias preguntas y respuestas relacionadas con ambos.

  1. Cómo cargar blob desde MySQL

    Ver por ejemplo Recuperar imagen almacenada como blob

  2. Cómo mostrar la imagen dinámicamente

    Ver por ejemplo Mostrar miniatura dinámicamente

También puede crear una etiqueta personalizada para mostrar la imagen.

1) crear una clase java de etiqueta personalizada y un archivo tld.

2) escribe lógica para mostrar una imagen como la conversión de byte [] a string por Base64.

por lo tanto, se usa para cada imagen, ya sea que solo muestre una o varias imágenes en una sola página jsp.

Usé la base de datos SQL SERVER y el código de la respuesta está de acuerdo. Todo lo que tiene que hacer es incluir una etiqueta en su página jsp y llamar a un servlet desde su atributo src como este

  

Aquí 1 es una identificación única de la imagen en la base de datos y la ID es una variable. Recibimos el valor de esta variable en servlet. En el código del servlet, tomamos la entrada del flujo binario de la columna correcta en la tabla. Esa es su imagen está almacenada en qué columna. En mi código utilicé la tercera columna porque mis imágenes se almacenan como datos binarios en la tercera columna. Después de recuperar los datos de la stream de entrada de la tabla, leemos su contenido en una secuencia de salida para que pueda escribirse en la pantalla. Aquí es

 import java.io.*; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.*; import javax.servlet.http.*; import model.ConnectionManager; public class DisplayImage extends HttpServlet { public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException { Statement stmt=null; String sql=null; BufferedInputStream bin=null; BufferedOutputStream bout=null; InputStream in =null; response.setContentType("image/jpeg"); ServletOutputStream out; out = response.getOutputStream(); Connection conn = ConnectionManager.getConnection(); int ID = Integer.parseInt(request.getParameter("ID")); try { stmt = conn.createStatement(); sql = "SELECT * FROM IMAGETABLE WHERE ID="+ID+""; ResultSet result = stmt.executeQuery(sql); if(result.next()){ in=result.getBinaryStream(3);//Since my data was in third column of table. } bin = new BufferedInputStream(in); bout = new BufferedOutputStream(out); int ch=0; while((ch=bin.read())!=-1) { bout.write(ch); } } catch (SQLException ex) { Logger.getLogger(DisplayImage.class.getName()).log(Level.SEVERE, null, ex); }finally{ try{ if(bin!=null)bin.close(); if(in!=null)in.close(); if(bout!=null)bout.close(); if(out!=null)out.close(); if(conn!=null)conn.close(); }catch(IOException | SQLException ex){ System.out.println("Error : "+ex.getMessage()); } } } } 

Después de la ejecución de su archivo jsp o html, verá la imagen en la pantalla.