1045 votes

Publication d'un Fichier et de Données Reposant de Webservices JSON

Cela va probablement être une question stupide, mais je vais avoir une de ces nuits. Dans une application que je développe, je suis en fournissant une API RESTful et nous voulons le client pour envoyer des données en JSON. Une partie de cette application nécessite que le client à télécharger un fichier (généralement une image) ainsi que des informations sur l'image.

Je vais avoir un moment difficile la traque comment cela se passe en une seule requête. Est-il possible de Base64 le fichier de données dans une chaîne JSON? Vais-je avoir besoin d'effectuer de 2 messages sur le serveur? Ne dois-je pas à l'aide de JSON pour cela?

Comme une note côté, nous sommes à l'aide de Grain sur le backend et ces services sont accessibles par le natif de clients mobiles (iPhone, Android, etc), si cela fait une différence

870voto

Daniel T. Points 7990

J'ai posé une question similaire ici:

http://stackoverflow.com/questions/3938569/how-do-i-upload-a-file-with-metadata-using-a-rest-web-service

En gros, vous avez trois choix:

  1. Base64 encode le fichier, au détriment de l'augmentation de la taille des données d'environ 33%.
  2. Envoyer d'abord le fichier dans un multipart/form-data POST, et retourner un code pour le client. Le client envoie ensuite les métadonnées avec l'ID et le serveur ré-associe les fichiers et les métadonnées.
  3. Envoyer les métadonnées d'abord, et de renvoyer un code pour le client. Le client envoie ensuite le fichier avec l'ID et le serveur ré-associe les fichiers et les métadonnées.

156voto

McStretch Points 10719

Vous pouvez envoyer le fichier et des données dans une requête à l'aide de la multipart/form-data type de contenu:

Dans de nombreuses applications, il est possible pour un utilisateur d'être présenté avec un formulaire. L'utilisateur devra remplir le formulaire, y compris les renseignements est tapé, généré par l'utilisateur, ou inclus dans des fichiers que l' l'utilisateur a sélectionné. Lorsque le formulaire est rempli, les données de la le formulaire est envoyé à l'utilisateur à la réception de la demande.

La définition de " MultiPart/Form-Data est dérivé de l'un de ces les applications...

À partir de http://www.faqs.org/rfcs/rfc2388.html:

"multipart/form-data" contient une série de pièces. Chaque partie est prévu pour contenir un contenu en-tête de disposition [RFC 2183] où l' disposition de type "form-data", et où la disposition contient un (supplémentaires) le paramètre "nom", où la valeur de la le paramètre est le nom du champ d'origine dans la forme. Par exemple, une partie peut contenir un en-tête:

Content-Disposition: form-data; name="utilisateur"

avec la valeur correspondant à l'entrée de la "utilisateur" sur le terrain.

Vous pouvez inclure des informations sur le fichier ou les informations d'un champ à l'intérieur de chaque section, entre les frontières. J'ai mis en œuvre avec succès un service RESTful qui est requis à l'utilisateur de saisir à la fois les données et d'un formulaire et d'multipart/form-data a parfaitement fonctionné. Le service a été construit à l'aide de Java/Printemps, et le client à l'aide de C#, donc, malheureusement, je n'ai pas de Graal exemples à vous donner sur la manière de configurer le service. Vous n'avez pas besoin d'utiliser JSON dans ce cas, puisque chaque "form-data" section vous donne un endroit pour spécifier le nom du paramètre et sa valeur.

La bonne chose sur l'utilisation de multipart/form-data, c'est que vous êtes à l'aide de HTTP-têtes définis par l', vous êtes donc coller avec le RESTE de la philosophie de l'aide existante HTTP outils pour créer votre service.

17voto

Rscorreia Points 91

Je sais que cette question est ancienne, mais dans les derniers jours, j'avais cherché tout le web à la solution de cette même question. J'ai graal RESTE des services web et Client iPhone que d'envoyer des photos, le titre et la description.

Je ne sais pas si ma méthode est la meilleure, mais c'est tellement facile et simple.

Je prends une photo à l'aide de la UIImagePickerController et de l'envoyer au serveur le NSData en utilisant les balises d'en-tête de requête pour envoyer l'image des données.

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"myServerAddress"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:UIImageJPEGRepresentation(picture, 0.5)];
[request setValue:@"image/jpeg" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"myPhotoTitle" forHTTPHeaderField:@"Photo-Title"];
[request setValue:@"myPhotoDescription" forHTTPHeaderField:@"Photo-Description"];

NSURLResponse *response;

NSError *error;

[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

Sur le côté serveur, je reçois la photo en utilisant le code:

InputStream is = request.inputStream

def receivedPhotoFile = (IOUtils.toByteArray(is))

def photo = new Photo()
photo.photoFile = receivedPhotoFile //photoFile is a transient attribute
photo.title = request.getHeader("Photo-Title")
photo.description = request.getHeader("Photo-Description")
photo.imageURL = "temp"    

if (photo.save()) {    

    File saveLocation = grailsAttributes.getApplicationContext().getResource(File.separator + "images").getFile()
    saveLocation.mkdirs()

    File tempFile = File.createTempFile("photo", ".jpg", saveLocation)

    photo.imageURL = saveLocation.getName() + "/" + tempFile.getName()

    tempFile.append(photo.photoFile);

} else {

    println("Error")

}

Je ne sais pas si j'ai des problèmes dans le futur, mais maintenant fonctionne bien dans un environnement de production.

8voto

lakhan_Ideavate Points 58

FormData Objets: Télécharger Des Fichiers À L'Aide D'Ajax

XMLHttpRequest Niveau 2 ajoute le support pour le nouveau FormData interface. FormData objets fournir un moyen facile de construire un ensemble de paires clé/valeur qui représente les champs de formulaire et de leurs valeurs, qui peut ensuite être facilement envoyés à l'aide de XMLHttpRequest méthode send ().

function AjaxFileUpload() { var file = document.getElementById("files"); //var file = fileInput; var fd = new FormData(); fd.append("imageFileData", file); var xhr = new XMLHttpRequest(); xhr.open("POST", '/ws/fileUpload.do'); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { alert('success'); } else if (uploadResult == 'success') alert('error'); }; xhr.send(fd); }

https://developer.mozilla.org/en-US/docs/Web/API/FormData

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X