All posts in Web Services

Upload et download de fichiers avec un web service (suite)

Ce message fait suite à mon précédent billet concernant le download et surtout l’upload de fichiers par Web Services SOAP.

Le bug 29 du projet jax-ws a bien été résolu, avec un petit bémol car la correction ne fonctionne qu’avec les Web Services à base de Servlet et non ceux basés sur les EJB Session. Cependant, pour transférer les données binaires MTOM utilise un transfer-coding de type chunked. Il s’agit d’une fonctionnalité d’HTTP 1.1 permettant d’envoyer ou de recevoir une requête HTTP par morceau.

La version 1.1 du protocole HTTP est vieille de plus de 10 ans. Malheureusement, dans de nombreuses organisations, sévissent encore des proxies web ne supportant que la version 1.0 !
Du coup, il n’est plus possible d’appliquer la propriété JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE sur le proxy du client. On se retrouve alors avec le problème initial ; on risque le « out of memory » côté client en téléchargeant sur le serveur (upload) un fichier volumineux.

Enfin, que les utilisateurs de DocDoku se rassurent, par défaut les échanges de fichiers se font par Web Services MTOM et en cas d’environnement réseau hostile (proxy http 1.0) le client bascule automatiquement dans un mode HTTP basique (multipart/form-data).

Upload et download de fichiers avec un web service

Comment faire pour « uploader » et « downloader » un fichier vers et depuis un web service ?
Très simple me diriez-vous et depuis longtemps. Il suffit d’utiliser SAAJ (SOAP with Attachments API for Java) ou encore mieux MTOM (Message Transmission Optimization Mechanism) pour bénéficier de l’assurance d’une compatibilité .Net/Java optimale.
En théorie cela semble simple mais quand on passe à la pratique, dans le contexte d’une application réelle, les choses se compliquent bigrement, en tout cas en ce qui concerne l’implémentation de JAXWS.
La plus grosse lacune de JAXWS au niveau MTOM est son incapacité à transmettre les données binaires sous forme de flux de bout en bout. Comme expliqué ici il est bien possible d’indiquer au client d’utiliser le mode « streaming » mais côté serveur rien à faire, l’ensemble des octets constituant le fichier est monté en mémoire.
Même côté client, JAXWS mériterait quelques améliorations. En effet il n’est pas possible de superviser la progression du transfert, de plus le mode « streaming » opère en appelant HttpURLConnection.setChunkedStreamingMode sur la connexion sous-jacente ce qui pose des problèmes car de nombreux serveurs web ou proxy ne supportent pas ce mode. Il serait intéressant que JAXWS calcule la taille du contenu à poster et invoque plutôt la méthode HttpURLConnection.setFixedLengthStreamingMode.

Conclusion de tout cela, pour uploader un fichier en http rien ne vaut d’utiliser directement HttpURLConnection et d’implémenter le basique et standard upload multipart/form-data.