Java - Freelance . fr » jax-rs https://java-freelance.fr Du java et du freelance Wed, 26 Jun 2013 11:46:03 +0000 fr-FR hourly 1 http://wordpress.org/?v=3.5 Upload multiple et asynchrone de fichiers https://java-freelance.fr/java/upload-multiple-et-asynchrone-de-fichiers https://java-freelance.fr/java/upload-multiple-et-asynchrone-de-fichiers#comments Thu, 09 Aug 2012 09:57:49 +0000 Jean-Baptiste https://java-freelance.fr/?p=1476 J’avoue avoir pas mal galéré à trouver mon bonheur car l’upload de fichiers en AJAX étant relativement récent, on trouve de nombreux exemples obsolètes sur la toile qui se basent sur une iframe… Ou ne fonctionnent pas avec Jersey coté serveur ^^
Trève de blabla, passons au code.

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 :

]]>
https://java-freelance.fr/java/upload-multiple-et-asynchrone-de-fichiers/feed 0
Web Application Description Language avec Jersey https://java-freelance.fr/java/web-application-description-language-avec-jersey https://java-freelance.fr/java/web-application-description-language-avec-jersey#comments Thu, 31 May 2012 22:11:42 +0000 Jean-Baptiste https://java-freelance.fr/?p=1405 Le langage de description d’application Web permet, comme son nom l’indique de décrire votre API REST dans un format XML http://www.w3.org/Submission/wadl/ . Cela peut paraître pénible à mettre en oeuvre, car à chaque fois qu’une ressource change, il faut mettre à jour le WADL.

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 :

  1. Créer une classe de type « com.sun.jersey.api.wadl.config.WadlGeneratorConfig »
  2. Passer cette classe en paramètre d’initialisation de votre servlet
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 ;)

]]>
https://java-freelance.fr/java/web-application-description-language-avec-jersey/feed 0