java - ejemplos - jsp tutorial
¿Cómo recuperar y visualizar imágenes desde una base de datos en una página JSP? (4)
¿Cómo puedo recuperar y mostrar imágenes de una base de datos en una página JSP?
Sugiero que aborden eso como dos problemas. Hay varias preguntas y respuestas relacionadas con ambos.
Cómo cargar blob desde MySQL
Ver por ejemplo Recuperar imagen almacenada como blob
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 <img>
en su página jsp y llamar a un servlet desde su atributo src como este
<img width="200" height="180" src="DisplayImage?ID=1">
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 corriente 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.
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
<img>
. - Para que encuentre una imagen, debe especificar su atributo
src
. - El atributo
src
necesita apuntar a una URLhttp://
válida y, por lo tanto, no a un archivo de ruta del sistema de archivos de disco localfile://
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[]
oInputStream
de la base de datos, la API de JDBC ofreceResultSet#getBytes()
yResultSet#getBinaryStream()
para esto, y la API de JPA ofrece@Lob
para esto. - En el Servlet, puede escribir este
byte[]
oInputStream
enOutputStream
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 deServletContext#getMimeType()
basado en la extensión de archivo de imagen que puede ampliar y / o sobrescribir a través de<mime-mapping>
enweb.xml
.
Eso debería ser. Casi escribe el código en sí mismo. Comencemos con HTML (en JSP ):
<img src="${pageContext.request.contextPath}/images/foo.png">
<img src="${pageContext.request.contextPath}/images/bar.png">
<img src="${pageContext.request.contextPath}/images/baz.png">
Si es necesario, también puede establecer dinámicamente src
con EL mientras itera usando JSTL :
<c:forEach items="${imagenames}" var="imagename">
<img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>
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 <Resource> in context.xml and declare as <resource-ref> 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 .