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 :
]]>Avec Jersey, l’implémentation de référence de JAX-RS (JSR311) pas de prise de tête, tout est générés automatiquement.
Il suffit de faire deux choses :
public class SchemaGenConfig extends WadlGeneratorConfig {
@Override
public List configure() {
return generator( WadlGeneratorJAXBGrammarGenerator.class).descriptions();
}
}
<servlet>
<servlet-name>
banner
</servlet-name>
<servlet-class>
com.lateralthoughts.commons.web.LateralCommonsServlet
</servlet-class>
<init-param>
<param-name>
com.sun.jersey.config.property.WadlGeneratorConfig
</param-name>
<param-value>
com.lateralthoughts.commons.web.wadl.SchemaGenConfig
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Le WADL est maintenant généré et accessible à cette adresse : http://localhost:port/maservlet/application.wadl
Pour aller plus loin, le wiki d’Oracle : https://wikis.oracle.com/display/Jersey/WADL
Merci à Aurélien Thieriot pour l’astuce