Je vais partager comment je fais cela. Je n'utilise pas google-cloud-endpoints, mais juste mon propre API basé sur REST, mais cela devrait être la même idée de toute façon.
Je vais le décrire étape par étape avec du code, avec un peu de chance ce sera clair. Vous adapteriez simplement la manière dont vous envoyez vos requêtes pour utiliser des endpoints au lieu de le faire de manière plus générique comme dans cet exemple. J'inclus un peu de code de base, mais j'exclus les blocs try/catch, la vérification des erreurs, etc. pour la concision.
Étape 1 (client)
Tout d'abord, le client demande une URL de téléversement au serveur :
HttpClient httpclient = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 10000); //Limite de temps d'attente
HttpGet httpGet = new HttpGet("http://example.com/blob/getuploadurl");
response = httpclient.execute(httpGet);
Étape 2 (serveur)
Côté serveur, la servlet de demande de téléversement ressemblerait à ceci :
String blobUploadUrl = blobstoreService.createUploadUrl("/blob/upload");
res.setStatus(HttpServletResponse.SC_OK);
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
out.print(blobUploadUrl);
out.flush();
out.close();
notez l'argument à createUploadUrl. C'est là où le client sera redirigé une fois que le téléversement réel aura été effectué. C'est là que vous gérerez le stockage de la blobkey et/ou l'URL de serveur et le renverrez au client. Vous devrez mapper une servlet pour cette URL, qui gèrera l'étape 4
Étape 3 (client) Retour au client pour envoyer le fichier réel à l'URL de téléversement en utilisant l'URL renvoyée à partir de l'étape 2.
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(uploadUrlReturnedFromStep2);
FileBody fileBody = new FileBody(thumbnailFile);
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("file", fileBody);
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost)
Une fois que cette requête est envoyée à la servlet de l'étape 2, elle sera redirigée vers la servlet que vous avez spécifiée dans le createUploadUrl()
précédemment
Étape 4 (serveur)
Retour côté serveur : Voici la servlet qui gère l'URL mappée à blob/upload
. Nous allons ici renvoyer la blobkey et l'URL de serveur au client dans un objet json :
List blobs = blobstoreService.getUploads(req).get("file");
BlobKey blobKey = blobs.get(0);
ImagesService imagesService = ImagesServiceFactory.getImagesService();
ServingUrlOptions servingOptions = ServingUrlOptions.Builder.withBlobKey(blobKey);
String servingUrl = imagesService.getServingUrl(servingOptions);
res.setStatus(HttpServletResponse.SC_OK);
res.setContentType("application/json");
JSONObject json = new JSONObject();
json.put("servingUrl", servingUrl);
json.put("blobKey", blobKey.getKeyString());
PrintWriter out = res.getWriter();
out.print(json.toString());
out.flush();
out.close();
Étape 5 (client)
Nous obtiendrons la blobkey et l'URL de serveur du json, puis nous l'enverrons avec l'ID utilisateur, etc. pour le stocker dans l'entité du datastore.
JSONObject resultJson = new JSONObject(resultJsonString);
String blobKey = resultJson.getString("blobKey");
String servingUrl = resultJson.getString("servingUrl");
List nameValuePairs = new ArrayList(2);
nameValuePairs.add(new BasicNameValuePair("userId", userId));
nameValuePairs.add(new BasicNameValuePair("blobKey",blobKey));
nameValuePairs.add(new BasicNameValuePair("servingUrl",servingUrl));
HttpClient httpclient = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 10000);
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
// Continuer à stocker l'URL de serveur (immédiatement disponible) dans le stockage local par exemple
Étape 6 (serveur) Stocker réellement tout dans le datastore (en utilisant objectify dans cet exemple)
final String userId = req.getParameter("userId");
final String blobKey = req.getParameter("blobKey");
final String servingUrl = req.getParameter("servingUrl");
ExampleEntity entity = new ExampleEntity();
entity.setUserId(userId);
entity.setBlobKey(blobKey);
entity.setServingUrl(servingUrl);
ofy().save().entity(entity);
J'espère que cela rend les choses plus claires. Si quelqu'un veut éditer la réponse pour utiliser des points de terminaison cloud au lieu de cet exemple plus générique, n'hésitez pas :)
A propos de l'URL de serveur
L'URL de serveur est un excellent moyen de servir des images à vos clients, en raison de la façon dont elle peut redimensionner dynamiquement les images à la volée. Par exemple, vous pouvez envoyer des images plus petites à vos utilisateurs LDPI en ajoutant simplement =sXXX
à la fin de l'URL de serveur. Où XXX est la taille en pixels de la plus grande dimension de votre image. Vous évitez complètement vos instances et ne payez que pour la bande passante, et l'utilisateur ne télécharge que ce dont il a besoin.
PS!
Il devrait être possible de s'arrêter à l'étape 4 et de le stocker directement là, en passant par exemple l'ID utilisateur à l'étape 3. Tous les paramètres doivent être envoyés à l'étape 4, mais je n'ai pas réussi à le faire fonctionner, c'est donc ainsi que je le fais actuellement, donc je le partage de cette façon car je sais que cela fonctionne.