IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Servlets/JSP Java Discussion :

Stockage récupère image BDD (POSTGRESQL)


Sujet :

Servlets/JSP Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 21
    Points : 12
    Points
    12
    Par défaut Stockage récupère image BDD (POSTGRESQL)
    Bonjour,
    J'ai un petit probleme, j'arrive a upper des images sur mon serveur, les stocker dans la BDD (bien qu'elles semblent mal stockees) type bytea.
    Cependant lorsque j'essaye de les recupere cela ne me donne rien.
    Je vous montre le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    BufferedImage bufferedImage = ImageIO.read(new File(path));
    // path correspond au chemin de stockage de l'image sur le serveur, c'est le bon j'arrive a l'affiche grace a un servlet d'affichage (avec l'idee de cette discution : <a href="http://www.developpez.net/forums/d604573/java/general-java/apis/io/creer-image-apartir-byte/" target="_blank">http://www.developpez.net/forums/d60...-apartir-byte/</a>)
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(bufferedImage, exten, baos); // exten correspond a l'extension de l'image
    baos.flush();
    byte[] imageInByte = baos.toByteArray();
    baos.close();
    A partir de cette endroit j'ai essaye de stocker l'image dans le BDD pour cela j'ai teste 2 methodes differentes :
    - Utiliser le "imageInByte" et utilise la method setBytes
    - Ouvrir le fichier fraichessement uppe sur le serveur pour recupere un InputStream dessus et utilise la method setBinaryStream

    En code ca donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    File file = new File(path); // Meme path que plus haut.
    FileInputStream fis = new FileInputStream(file);
     
    ps.setInt(1, Integer.parseInt(42));
    ps.setBinaryStream(2, fis, (int)file.length());
    /*ps.setBytes(2, sto);*/
    ps.executeUpdate();
    Ensuite je recupere ces donnees avec un getBinaryStream ou getBytes en fonction de la fonction que j'utilise.

    Jusque la ca marche bien que apres certains tests j'ai essaye de compare la taille de "imageInByte" avec celle recupere de la BDD (et la je me rencontre que la taille est differente. J'ai teste la taille juste avant d'upper dans la BDD elle est aussi differente entre ce que je stock et ce que je recupere).

    Ensuite pour l'affichage j'ai encore teste plusieurs methodes sur "imageInByte" et sur ce que je recupere de la BDD :
    - J'ai recreer les deux images

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    File monImage = new File(newPATH); //avec l'extention de base de l'image
       FileOutputStream ostreamImage = new FileOutputStream(monImage);
       byte[] buffer = new byte[1024];
       int length = 0;
       InputStream istreamImage = new ByteArrayInputStream(imageInByte); // ou getBinaryStream(1) ou new ByteArrayInputStream(getBytes(1))
       while((length = istreamImage.read(buffer)) != -1)
       {
           response.getWriter().print("buffer :" + buffer + " length : " + length + "\n");
           ostreamImage.write(buffer, 0, length);
        }
    Avec "imageInByte" cela me redonne la bonne image meme taille, en recuperant de la BDD impossible d'affiche l'image et taille differente (pour ca j'ai ete checker directement sur le serveur).

    - J'ai aussi l'affichage par la response comme montrer dans ce topic (http://www.developpez.net/forums/d60...-apartir-byte/)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    response.setContentType("image/" + exten);
         InputStream is = new ByteArrayInputStream(imageInByte); // ou avec getBytes ou getBinaryStream
         BufferedImage image = ImageIO.read(is);
         ImageIO.write(image, exten, response.getOutputStream());
    Meme probleme que plus haut, ca marche avec "imageInByte" mais rien a faire avec ce que je recois de la BDD.


    Donc je pense que ca vient surement au moment du stockage mais je ne vois comment, si quelqu'un a une idee.

    PS : J'utilise Tomcat 7.0, jre6, jdk1.6 et postgresql-8.4-701.jdbc4 comme jar pour la connection avec la BDD et Postgresql 9.0.

    Merci d'avance.

  2. #2
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 21
    Points : 12
    Points
    12
    Par défaut
    Quelqu'un aurait une petite idée d'où peut venir mon problème ? =$

  3. #3
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Peux-tu montrer le code d'extraction de la DB ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 21
    Points : 12
    Points
    12
    Par défaut
    J'execute une requete qui me recupere juste le champ bytea de ma table ou sont stockees les images.
    Le resultat est retourne dans res.

    Ensuite j'ai essaye deux methodes :

    - image stocker dans la base de donnee grace a la method setBinaryStream :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    File monImage = new File(chemin_nouvelle_image); //avec la bonne extension
    FileOutputStream ostreamImage = new FileOutputStream(monImage);
    if (res != null && res.next())
    {
        byte[] buffer = new byte[1024];
        int length = 0;
        InputStream istreamImage = res.getBinaryStream("pic");
        while((length = istreamImage.read(buffer)) != -1)
        {
            ostreamImage.write(buffer, 0, length);
        }
    }
    Avec cette methode un fichier image est cree sur le serveur mais impossible de l'ouvrir et il ne fait pas la meme taille que l'original.

    - image stocker grace a la method setBytes et j'essaye de l'afficher directement sur le navigateur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    response.setContentType("image/" + exten);
     
    byte[] imgBytes = res.getBytes("pic");
    InputStream is = new ByteArrayInputStream(imgBytes);
    BufferedImage image = ImageIO.read(is);
    ImageIO.write(image, exten, response.getOutputStream());
    Ici l'image ne s'affiche pas.

    J'ai essaye les deux methodes avec getBinaryStream ou getBytes ca ne change rien. Le resultat est le meme.

  5. #5
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Bon, voilà (dans le principe) comment je procèderais :
    Je stockerais dans la BDD 2 informations (en plus de la clé primaire) :
    - le type mime
    - le contenu de l'image

    Pour l'extraction, tu peux t'inspirer de ceci (de loin pas optimisé)

    La page jsp devant afficher les images : de simple balises <img>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <html>
    <body>
    Image id 1 <img src="<%=request.getContextPath()%>/getImage?id=1"/> <br/>
    Image id 2 <img src="<%=request.getContextPath()%>/getImage?id=2"/> <br/>
    </body>
    </html>
    La servlet getImage
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    package test;
     
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    public class GetImage extends HttpServlet
    {
        private static final long serialVersionUID = 1;
     
        @Override
        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
                    IOException
        {
            Connection connection = null;
            InputStream is = null;
            try
            {
                Class.forName("com.mysql.jdbc.Driver");
                connection = DriverManager.getConnection("jdbc:mysql:///test", "...", "...");
     
                String id = request.getParameter("id");
     
                PreparedStatement pstmt2 = connection.prepareStatement("select mimeType,data from images where id=?");
                pstmt2.setInt(1, Integer.parseInt(id));
                ResultSet rs = pstmt2.executeQuery();
                if (rs.next())
                {
                    ServletOutputStream os = response.getOutputStream();
                    String mime = rs.getString(1);
                    response.setContentType(mime);
     
                    is = rs.getBinaryStream(2);
                    byte[] bytes = new byte[1024];
                    while (is.read(bytes) != -1)
                    {
                        os.write(bytes);
                    }
                    os.flush();
                    os.close();
                }
     
            }
            catch (Exception e)
            {
                System.out.println(e.getMessage());
            }
            finally
            {
                if (connection != null)
                {
                    try
                    {
                        connection.close();
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
        }
    }
    Pour info, j'ai inséré les images comme ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    package test;
     
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    public class UploadImage extends HttpServlet
    {
        private static final long serialVersionUID = 1;
     
        @Override
        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException,
                    IOException
        {
            Connection connection = null;
            InputStream is = null;
            try
            {
                String mime = request.getParameter("mime");
                String path = request.getParameter("path");
                is = new FileInputStream(path);
     
                Class.forName("com.mysql.jdbc.Driver");
                connection = DriverManager.getConnection("jdbc:mysql:///test", "...", "...");
                PreparedStatement pstmt = connection.prepareStatement("insert into images(mimeType, data) values(?, ?)");
                pstmt.setString(1, mime);
                pstmt.setBinaryStream(2, is);
                pstmt.execute();
     
            }
            catch (Exception e)
            {
                System.out.println(e.getMessage());
            }
            finally
            {
                if (connection != null)
                {
                    try
                    {
                        connection.close();
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
        }
    }
    La table a été créée par (MySQL)
    CREATE TABLE IF NOT EXISTS `test`.`images` (
    `id` INT NULL AUTO_INCREMENT ,
    `mimeType` VARCHAR(45) NULL ,
    `data` LONGBLOB NULL ,
    PRIMARY KEY (`id`) );
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 21
    Points : 12
    Points
    12
    Par défaut
    Je vai essayer tout ca au plus vite et je te tiens au courant.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 21
    Points : 12
    Points
    12
    Par défaut
    Je viens de tester ta methode, ca ne marche pas toujours pas.
    De plus, la method setBinaryStream(int, InputStream) n'est apparament pas implemente ... (j'avais deja eu ce bug j'ai donc utiliser la methode setBinarayStream(int, InputStream, int).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ps.setBinaryStream(2, is, is.available())
    De plus le probleme semble plus venir lors du stockage puisque si j'utilise ta servlet getImage avec (path correspond au chemin de l'image) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    InputStream is = new FileInputStream(path);
    au lieu de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    is = res.getBinaryStream(2);
    Cela fonction nickel.
    J'ai absolument plus aucune idee >.< et j'y comprend pu rien.

    Ma table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    CREATE TABLE table_pics
    (
      "PIC_ID" bigint,
      "PIC" bytea
    )

  8. #8
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Après une petite recherche sur le net, je dirais que ton problème est PostgreSQL
    Il ne connait même pas le type BLOB !

    Regarde cet exemple, peut-être que ça t'aidera...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 21
    Points : 12
    Points
    12
    Par défaut
    Justement j'en avais entendu parler mais vu que je debute je voulais plutot rester sur un truc simple et eviter d'avoir a recreer l'image sur le serveur (juste "jouer" avec en memoire aurai pu être plus clean).
    Et vu que j'avais trouver 2 petits tuto bien sympa (ici et ici).

    Enfin pas grave je vai partir sur les histoires de OID etc
    Ca me permettra d'apprendre de nouveaux trucs xD.

    Enfin je suis toujours preneur si quelqu'un a une idee.

  10. #10
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    C'est une contrainte d'utiliser PostgreSQL ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 21
    Points : 12
    Points
    12
    Par défaut
    Oui c'est ca le probleme, comme le fait de stocker directement dans la base de donnee pour l'exporter plus facilement.

  12. #12
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 310
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 310
    Points : 9 522
    Points
    9 522
    Billets dans le blog
    1
    Par défaut
    Stocker dans la base de données est une bonne chose, trop souvent ignorée...
    PostgreSQL, je ne sais pas... je n'ai jamais utilisé... mais ne pas avoir le support des BLOB ou CLOB est dommage, même si on peut le contourner apparemment.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 21
    Points : 12
    Points
    12
    Par défaut
    Mais bon apparament vu les tests que j'ai fait, ca devrait bien venir du stockage dans la BDD vu que la taille de l'original (image) et celle extraite sont toujours differentes.
    Et de plus j'arrive parfaitement a afficher l'image avec les info (en bytes[] ou inputstream) que je stock dans la BDD, mais lorsque je l'ai recupere ...
    Je vai refaire des tests en local pouvoir si ca peut pas venir de la version de mon postgres ou du connecteur JDBC (pour j'ai recupere le dernier).

    Je viens de tester avec les OID ca marche nickel, mais j'aimerai bien trouvais comment les utiliser sans passer par un fichier temp.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 21
    Points : 12
    Points
    12
    Par défaut
    Bon beh mon probleme est corrige ...
    Probleme de JDBC ... Il faut prendre le 9.0dev-800 JDBC 4

    Merci de ton aide OButterlin.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Stockage d'images et affichage
    Par jh0483 dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 06/10/2005, 14h55
  2. [MySQL] Problème par rapport au tutoriel sur le stockage des images en base
    Par dark_vidor dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 25/09/2005, 10h37
  3. Stockage d'images
    Par Etienne1 dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 02/09/2004, 15h49
  4. stockage d'images dans Mysql
    Par sessime dans le forum Bases de données
    Réponses: 3
    Dernier message: 23/02/2004, 16h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo