web-dev-qa-db-fra.com

Comment récupérer et afficher des images d'une base de données dans une page JSP?

Comment récupérer et afficher des images d'une base de données dans une page JSP?

26
krunal

Voyons par étapes ce qui devrait arriver:

  • JSP est essentiellement une technologie d'affichage qui est censée générer une sortie HTML.
  • Pour afficher une image en HTML, vous avez besoin de l'élément HTML <img>.
  • Pour lui permettre de localiser une image, vous devez spécifier son attribut src.
  • L'attribut src doit pointer vers une URL http:// Valide et donc pas un chemin d'accès au système de fichiers du disque local file:// Car cela ne fonctionnerait jamais lorsque le serveur et le client s'exécutent physiquement différemment. Machines.
  • L'URL de l'image doit avoir l'identifiant de l'image dans le chemin de demande (par exemple http://example.com/context/images/foo.png) Ou comme paramètre de demande (par exemple http://example.com/context/images?id=1).
  • Dans le monde JSP/Servlet, vous pouvez laisser un Servlet écouter sur un certain modèle d'URL comme /images/*, Afin que vous puissiez simplement exécuter du code Java sur des URL spécifiques).
  • Les images sont des données binaires et doivent être obtenues en tant que byte[] Ou InputStream à partir de la base de données, la API JDBC offre la ResultSet#getBytes() et ResultSet#getBinaryStream() pour cela, et API JPA propose @Lob pour cela.
  • Dans le servlet, vous pouvez simplement écrire ceci byte[] Ou InputStream dans le OutputStream de la réponse de la manière habituelle Java IO .
  • Le côté client doit être informé que les données doivent être traitées comme une image, donc au moins l'en-tête de réponse Content-Type doit également être défini. Vous pouvez obtenir le bon via ServletContext#getMimeType() basé sur l'extension du fichier image que vous pouvez étendre et/ou remplacer via <mime-mapping> Dans web.xml.

Ça devrait être ça. Il écrit presque le code lui-même. Commençons par HTML (dans 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 nécessaire, vous pouvez également définir dynamiquement src avec EL tout en itérant en utilisant JSTL :

<c:forEach items="${imagenames}" var="imagename">
    <img src="${pageContext.request.contextPath}/images/${imagename}">
</c:forEach>

Ensuite, définissez/créez un servlet qui écoute les requêtes GET sur le modèle d'URL de /images/*, L'exemple ci-dessous utilise du JDBC Vanilla ordinaire pour le travail:

@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);
        }
    }

}

C'est ça. Si vous vous inquiétez de HEAD et de la mise en cache des en-têtes et de la réponse appropriée à ces demandes, utilisez ceci modèle abstrait pour le servlet de ressource statique .

Voir également:

66
BalusC

Je vous suggère de traiter cela comme deux problèmes. Il y a plusieurs questions et réponses liées aux deux.

  1. Comment charger un blob depuis MySQL

    Voir par exemple Récupérer l'image stockée sous forme de blob

  2. Comment afficher l'image dynamiquement

    Voir par exemple Afficher la vignette dynamiquement

6
ewernli

Essayez de vider et de fermer le flux de sortie s'il ne s'affiche pas. Blob image = rs.getBlob(ImageColName);InputStream in = image.getBinaryStream(); // Sortie du blob dans HttpServletResponse response.setContentType("image/jpeg");BufferedOutputStream o = new BufferedOutputStream(response.getOutputStream());

    byte by[] = new byte[32768];
    int index = in.read(by, 0, 32768);
    while (index != -1) {
        o.write(by, 0, index);
        index = in.read(by, 0, 32768);
    }
    o.flush();
    o.close();
0
Sonam Tshering