Importer des images dans un formulaire de modification de produit
Cet exemple montre comment ajouter la fonctionnalité d'upload d'image lors de la modification d'un produit dans une application Spring MVC.
1. Configuraton du résolveur multipart
Dans le fichier de configuration Spring MVC (springmvc.xml), déclarez un bean CommonsMultipartResolver pour gérer les téléversements :
<!-- Résolveur multipart pour upload de fichiers -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- Taille maximale du fichier : 5 Mo -->
<property name="maxUploadSize" value="5242880" />
</bean>
Ajoutez les dépendances commons-fileupload-1.2.2.jar et commons-io-2.4.jar dans le classpath (WEB-INF/lib).
2. Formulaire JSP avec l'attribut enctype
Dans la page editItems.jsp, le formulaire doit avoir enctype="multipart/form-data" et inclure un champ de type file.
<form id="itemForm" action="${pageContext.request.contextPath }/items/editItemsSubmit.action" method="post" enctype="multipart/form-data">
<input type="hidden" name="id" value="${items.id }" />
<table>
<tr>
<td>Nom du produit</td>
<td><input type="text" name="name" value="${items.name }" /></td>
</tr>
<tr>
<td>Prix</td>
<td><input type="text" name="price" value="${items.price }" /></td>
</tr>
<tr>
<td>Date de fabrication</td>
<td><input type="text" name="createtime" value="<fmt:formatDate value="${items.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" /></td>
</tr>
<tr>
<td>Image du produit</td>
<td>
<c:if test="${items.pic != null}">
<img src="/pic/${items.pic}" width="100" height="100" />
<br />
</c:if>
<input type="file" name="items_pic" />
</td>
</tr>
<tr>
<td>Description</td>
<td><textarea rows="3" cols="30" name="detail">${items.detail }</textarea></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Valider" /></td>
</tr>
</table>
</form>
3. Contrôleur Spring MVC
Le contrôleur reçoit le fichier téléversé via le paramètre MultipartFile, génère un nouveau nom de fichier et le sauvegarde sur le disque.
Première approche : dossier virtuel Tomcat
Configurez un contexte Tomcat (dans server.xml) pour mapper le chemin /pic vers un dossier physique (ex : D:\\upload\\images).
<Context docBase="D:\\upload\\images" path="/pic" reloadable="false"/>
Dans le contrôleur :
@RequestMapping("/editItemsSubmit")
public String processEditSubmit(Model model,
HttpServletRequest request,
Integer id,
@Validated(ValidGroup1.class) ItemsCustom itemsCustom,
BindingResult bindingResult,
MultipartFile itemsPic) throws Exception {
if (bindingResult.hasErrors()) {
List<ObjectError> errors = bindingResult.getAllErrors();
model.addAttribute("allErrors", errors);
model.addAttribute("items", itemsCustom);
return "items/editItems";
}
String nomFichierOriginal = itemsPic.getOriginalFilename();
if (itemsPic != null && nomFichierOriginal != null && nomFichierOriginal.length() > 0) {
String dossierCible = "D:\\upload\\images\\";
String extension = nomFichierOriginal.substring(nomFichierOriginal.lastIndexOf("."));
String nouveauNom = UUID.randomUUID().toString() + extension;
File fichier = new File(dossierCible + nouveauNom);
itemsPic.transferTo(fichier);
itemsCustom.setPic(nouveauNom);
}
itemsService.updateItems(id, itemsCustom);
return "success";
}
Seconde approche : dossier dans l'application Web
Placez les images dans le répertoire resources/images/ du projet (sous WebRoot/ par exemple). Utilisez ServletContext.getRealPath() pour obtenir le chemin absolu.
@RequestMapping("/editItemsSubmit")
public String processEditSubmit(Model model,
HttpServletRequest request,
Integer id,
@Validated(ValidGroup1.class) ItemsCustom itemsCustom,
BindingResult bindingResult,
MultipartFile itemsPic) throws Exception {
if (bindingResult.hasErrors()) {
List<ObjectError> errors = bindingResult.getAllErrors();
model.addAttribute("allErrors", errors);
model.addAttribute("items", itemsCustom);
return "items/editItems";
}
String nomFichierOriginal = itemsPic.getOriginalFilename();
if (itemsPic != null && nomFichierOriginal != null && nomFichierOriginal.length() > 0) {
String cheminReel = request.getServletContext().getRealPath("resources/images/");
String extension = nomFichierOriginal.substring(nomFichierOriginal.lastIndexOf("."));
String nouveauNom = UUID.randomUUID().toString() + extension;
File fichier = new File(cheminReel + nouveauNom);
itemsPic.transferTo(fichier);
itemsCustom.setPic(nouveauNom);
}
itemsService.updateItems(id, itemsCustom);
return "success";
}
Pour que les images soient accessibles depuis le nvaigateur, ajoutez une configuration de ressources statiques dans springmvc.xml :
<mvc:resources mapping="/resources/**" location="/resources/" />
Et modifiez la balise <img> dans le JSP pour pointer vers le bon chemin :
<c:if test="${items.pic != null}">
<img src="${pageContext.request.contextPath }/resources/images/${items.pic}" width="100" height="100" />
</c:if>
Les fichiers sont alors sauvegardés dans tomcat/webapps/application/resources/images/ et affichés correctement.