miércoles, 17 de junio de 2020

Mostrar imágenes en JSP con Servlet

Consideramos la clase "Espacios" que proviene de la siguiente estructura SQL (Se ha obviado intencionalmente a la clave foránea en el campo "tipo"):
-- -----------------------------------------------------
-- Table espacios
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS espacios (
  idespacios INT NOT NULL AUTO_INCREMENT,
  piso TINYINT NOT NULL,
  precio DOUBLE(6,2) NOT NULL,
  ubicacion VARCHAR(25) NULL,
  tipo TINYINT NULL,
  imagen BLOB NULL,
  PRIMARY KEY (idespacios)
  )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;


Su clase en Java con el patrón DTO sería:
package dto;

public class Espacios {

    private Integer idespacios;
    private Integer piso;
    private Double precio;
    private String ubicacion;
    private Integer tipo;
    private byte[] imagen;

    public Espacios() {
    }

    /* Métodos Setter y getter */

}


El atributo imagen no se emplea, pero será de utilidad si convertimos el proyecto a uno de escritorio.
Su Interfaz e implementación DAO son:
package dao;

import java.util.List;
import dto.Espacios;

public interface DaoEspacios {

    public byte[] espaciosImg(Integer id);

    public String getMessage();
}

package dao.impl;

import biblioteca.ConectaBD;
import dao.DaoEspacios;
import dto.Espacios;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class DaoEspaciosImpl implements DaoEspacios {

    private final ConectaBD conectaDb;
    private String mensaje;

    public DaoEspaciosImpl() {
        this.conectaDb = new ConectaBD();
    }

    @Override
    public byte[] espaciosImg(Integer id) {
        byte[] img = null;
        StringBuilder sql = new StringBuilder();
        sql.append("SELECT ")
                .append("imagen")
                .append(" FROM espacios WHERE idespacios = ?");
        try (Connection cn = conectaDb.conexionDB()) {
            PreparedStatement ps = cn.prepareStatement(sql.toString());
            ps.setInt(1, id);
            try (ResultSet rs = ps.executeQuery()) {
                if (rs.next()) {
                    Blob blob = rs.getBlob(1);
                    if (blob != null) {
                        byte[] bytes = blob.getBytes(1, (int) blob.length());
                        blob.free();
                        img = bytes;
                    }
                } else {
                    img = null;
                }
            } catch (SQLException e) {
                mensaje = e.getMessage();
            }
        } catch (SQLException e) {
            mensaje = e.getMessage();
        }
        return img;
    }

    @Override
    public String getMessage() {
        return mensaje;
    }
}


El servlet que permite mostrar la imagen sería:
package web.servlet;

import biblioteca.DeString;
import dao.DaoEspacios;
import dao.impl.DaoEspaciosImpl;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "ImagenServlet", urlPatterns = {"/Imagen"})
public class ImagenServlet extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("image/jpg");
        DaoEspacios daoEspacios = new DaoEspaciosImpl();
        Integer id = DeString.aInteger(request.getParameter("id"));
        try {
            byte[] data = daoEspacios.espaciosImg(id);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            output.write(data, 0, data.length);
            response.setContentLength(output.size());
            try (OutputStream out = response.getOutputStream()) {
                output.writeTo(out);
                out.flush();
            }
        } catch (IOException ex) {
            System.err.println(String.format("%s - %s", daoEspacios.getMessage(), ex.getMessage()));
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
}


El URL para mostrar una imagen sería por ejemplo: http://localhost:8084/Demo/Imagen?id=8 donde el valor que cambia es el número "8" por el "id" del registro del que se desea mostrar la imagen.

Ejemplo:

Dentro de un JSP el código tendría la siguiente forma:

      <img src="Imagen?id=8" alt="img"/>
   


Ese valor 8 se puede reemplazar con código de manera que recibe el "id" esperado como en esta porción de código que captura el id mediante una estructura que lista todos los espacios con JSTL.

      <img src="Imagen?id=${f.idespacios}" alt="img"/>
   




No hay comentarios:

Publicar un comentario