Recevez les mises à jour gratuites du blog par Email : »» Garanti sans spam indésirable ««

MySQL : Enregistrement et récupération d’images pour afficher dans une JSP

de Mimie le 16 janvier 2010

Rubrique : Programmation

Présentation

Nous allons vous présenter dans cet article un moyen de réaliser l’enregistrement et la récupération d’images en base de données au format BLOB (MySQL). Les images que l’on souhaite enregistrer dans l’exemple sont des images présentes sur Internet, nous n’avons d’elles uniquement leurs URL pointant :

Remarque : il serait simple de faire la même chose avec des images sur son poste ou sur le réseau local.

Base de données

La table crée pour l’occasion contient 3 champs : « id », « name » et « image », nous comprenons que les images seront stockées dans le champ « image » :

  • Script de création de la table stockant les images
CREATE TABLE  `des_geeks`.`cards` (
   `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
   `name` VARCHAR( 50 ) NOT NULL ,
   `image` BLOB NOT NULL
) ENGINE = INNODB;
  • Enregistrement d’une ligne dans la table à l’aide de Spring JDBC, notons que le champ contenant l’image est de type byte[]
public void insertCard(CardBean card) throws DataAccessException {
	String QUERY_INSERT_CARD = "INSERT INTO CARDS (NAME, IMAGE) VALUES (?, ?)";
	getJdbcTemplate().update(
		QUERY_INSERT_CARD,
		new Object[] {
			card.getName(),
			card.getImage()
		},
		new int[] {
			Types.VARCHAR,
			Types.BLOB
		}
	);
}
  • Récupération d’une ligne de la table en prenant soin de convertir le BLOB récupéré en byte[]
public CardBean selectCard(Integer cardId) throws DataAccessException {
	String QUERY_GET_CARD = "SELECT ID, NAME, IMAGE FROM CARDS WHERE ID = ?";
	List results = getJdbcTemplate().query(
		QUERY_GET_CARD,
		new Object[] { cardId},
		new int[] { Types.INTEGER },
		new RowMapper() {
			public Object mapRow(ResultSet rs, int arg) throws SQLException {
				CardBean cardBean = new CardBean();
				cardBean.setId(rs.getInt("ID"));
				Blob image = rs.getBlob("IMAGE");
				if (image != null) {
					cardBean.setImage(image.getBytes(1, (int) image.length()));
				}
				return cardBean;
			}
		}
	);
	return results.isEmpty() ? null : (CardBean) results.get(0);
}

Mise en place

La récupération de l’image via son URL se fait grâce à la classe Java javax.imageio.ImageIO qui permet d’obtenir un objet de type java.awt.image.BufferedImage. Ensuite cet objet est converti en byte[] afin d’être facilement utilisable par les différentes couches de l’application (présentation -> métier -> persistance)  :

BufferedImage imageBuffered = ImageIO.read(new URL("http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=180454&type=card"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(imageBuffered, "jpg", out);
byte[] bytes = out.toByteArray();

L’enregistrement de l’image en base vous a été présenté précédemment ainsi que sa récupération, voici donc le mécanisme final qui vous permettra d’afficher l’image récupérée au format byte[] dans votre page JSP :

    1. Afficher votre image à l’aide de la balise classique <img> en pointant le source vers un service qui se chargera d’injecter l’image, ici le service est mis en place avec Struts
<c:forEach var="card" items="${requestScope['cardsList']}">
    <li>
    	<span id="card_id_${card.id}">${card.id}</span>
    	<span id="card_name_${card.id}">${card.name}</span>
    	<span id="card_image_${card.id}"><img src="${ctx}/card.do?action=displayImage&cardId=${card.id}"/></span>
    </li>
</c:forEach>
    1. Voici le service (l’action Struts dans notre cas) qui permet de récupérer puis d’injecter l’image grâce à son identifiant
public ActionForward displayImage(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception {
	Integer cardId = Integer.valueOf(request.getParameter("cardId"));
	// get card (and image) from database
	CardBean card = cardService.findCardById(cardId);
	if (card.getImage() != null) {
		// display the image
		response.setContentType("image/jpg");
		OutputStream o = response.getOutputStream();
		o.write(card.getImage());
		o.flush();
		o.close();
	}
	return null;
}

Conclusion

Mine de rien c’est un sujet récurrent qui pose beaucoup de problèmes à mettre en place, j’espère donc vous avoir dépanné pour ceux qui souhaiteraient, comme moi en ce moment, stocker vos images en base et les afficher dans les pages de votre site.

Sources disponibles ici

Cet article a été écrit par :

– qui a déjà rédigé 123 posts sur Des Geeks et des lettres.

Passionné d'informatique et développeur JavaEE de métier, je me consacre principalement à écrire des billets sur les sujets du Web et de la programmation Web. Ce blog est un espace qui me permet de partager mes découvertes avec vous et me sert accessoirement de pense bête !

Contacter l'auteur

Jetez aussi un oeil sur :

{ 2 commentaires… à vous de vous exprimer ! }

1 Greg janvier 16, 2010 à 19 h 05 min

Bon ben voilà qui est fait et bien fait :)

Répondre

2 Mimie janvier 16, 2010 à 20 h 11 min

Merci :-) le principe va être mis en place pour mon futur site sur Magic the Gathering ^^, ça va roxer !

Répondre

Laissez un Commentaire

Article précédent:

Article suivant: