Premièrement, ajouter un champ input acceptant l’ajout de plusieurs fichiers :
<input id="files" multiple="multiple" name="file[]" type="file">
Ensuite, uploadons les fichiers en utilisant les « FormData » d’HTML5 :
var upload = function (file) { var data = new FormData(); data.append('name', file.name); data.append('file', file); $.ajax({ url:'/photo', data:data, cache:false, contentType:false, processData:false, type:'POST' }).error(function () { alert("unable to upload " + file.name); }) .done(function (data, status) { doSomethingUseful(data); }); }; function multiUpload(files) { for (var i = 0; i < files.length; i++) { // Only upload images if (/image/.test(files[i].type)) { upload(files[i]); } } } $(document).ready(function () { $("#files").change(function (e) { multiUpload(e.target.files); }) });
Coté serveur, avec Jersey, il faut inclure le module « multipart » :
<dependency> <groupId>com.sun.jersey.contribs</groupId> <artifactId>jersey-multipart</artifactId> <version>1.13</version> </dependency>
Ensuite le code est plutôt simple :
import javax.inject.Inject; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import com.sun.jersey.core.header.FormDataContentDisposition; import com.sun.jersey.multipart.FormDataParam; import java.io.IOException; import org.apache.log4j.Logger; import org.springframework.stereotype.Controller; @Controller @Path("/photo") public class PhotoResource extends AbstractResource { private static final Logger LOG = Logger.getLogger(PhotoResource.class); @Inject private FileRepository fileRepository; @GET @Produces("image/png") @Path("/{photoId}") public byte[] photo(@PathParam("photoId") String photoId) { try { return fileRepository.get(photoId); } catch (IOException e) { LOG.warn("When get photo id : " + photoId, e); throw ResourceException.notFound(); } } @POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_PLAIN) public String addPhoto(@FormDataParam("file") byte[] photo, @FormDataParam("file") FormDataContentDisposition fileDetail) { String photoId = null; try { photoId = fileRepository.save(photo); } catch (IOException e) { LOG.error("unable to add photo", e); throw ResourceException.error(e); } return photoId; } }
Et pour s’amuser, stockons les fichiers dans Mongodb grace à GridFS :
import javax.annotation.PostConstruct; import javax.inject.Inject; import com.mongodb.gridfs.GridFS; import com.mongodb.gridfs.GridFSInputFile; import java.io.IOException; import org.apache.commons.io.IOUtils; import org.bson.types.ObjectId; import org.jongo.Jongo; import org.springframework.stereotype.Repository; @Repository public class FileRepository { private Jongo jongo; private GridFS files; @Inject public FileRepository(Jongo jongo) { this.jongo = jongo; } @PostConstruct public void afterPropertiesSet() throws Exception { files = new GridFS(jongo.getDatabase()); } /** * Save a file and return the corresponding id */ public String save(byte[] file) { GridFSInputFile savedFile = this.files.createFile(file); savedFile.save(); return savedFile.getId().toString(); } /** Return the file */ public byte[] get(String fileId) throws IOException { return IOUtils.toByteArray(files.findOne(new ObjectId(fileId)).getInputStream()); } } }
Et si vous voulez faire du drag and drop, il suffit d’inclure ce plugin jQuery : drop.js et de faire comme ceci :
$(document).ready(function () { $('body').dropArea(); $('body').bind('drop', function (e) { e.preventDefault(); e = e.originalEvent; multiUpload(e.dataTransfer.files); }); });
Sources :
]]>