我将分享我是如何做到这一点的。我没有使用google-cloud-endpoints,而只是我自己的基于rest的api,但无论哪种方式都应该是相同的想法。
我将用代码一步一步地列出它,希望它会很清楚。您只需调整发送请求的方式以使用端点,而不是像本例中那样更通用。为了简洁起见,我包括了一些样板文件,但不包括 try/catch、错误检查等。
第 1 步(客户)
第一个客户端从服务器请求上传 url:
HttpClient httpclient = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 10000); //Timeout Limit
HttpGet httpGet = new HttpGet("http://example.com/blob/getuploadurl");
response = httpclient.execute(httpGet);
第 2 步(服务器)
在服务器端,上传请求 servlet 看起来像这样:
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();
注意 createUploadUrl 的参数。这是实际上传完成后将重定向客户端的位置。这就是您将处理存储 blobkey 和/或提供 url 并将其返回给客户端的地方。您必须将 servlet 映射到该 url,它将处理第 4 步
第 3 步(客户端)
再次返回客户端,使用第 2 步返回的 url 将实际文件发送到上传 url。
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)
在步骤 2 中将此请求发送到 servlet 后,它将被重定向到您在createUploadUrl()
前面指定的 servlet
第 4 步(服务器)
回到服务器端:这是处理映射到 url 的 servlet blob/upload
。我们将在此处以 json 对象的形式将 blobkey 和服务 url 返回给客户端:
List<BlobKey> 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();
第 5 步(客户)
我们将从 json 中获取 blobkey 和服务 url,然后将其与用户 ID 等一起发送以存储在数据存储实体中。
JSONObject resultJson = new JSONObject(resultJsonString);
String blobKey = resultJson.getString("blobKey");
String servingUrl = resultJson.getString("servingUrl");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(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);
// Continue to store the (immediately available) serving url in local storage f.ex
第 6 步(服务器)
实际将所有内容存储在数据存储中(在此示例中使用 objectify)
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);
我希望这能让事情更清楚。如果有人想编辑答案以使用云端点而不是这个更通用的示例,请随意:)
关于投放网址
服务 url 是向客户提供图像的好方法,因为它可以动态地动态缩放图像。例如,您可以将较小的图像发送给您的 LDPI 用户,只需=sXXX
在服务 url 的末尾附加即可。其中 XXX 是图像最大尺寸的像素大小。你完全避免了你的实例,只为带宽付费,用户只下载她需要的东西。
PS!
应该可以在第 4 步停止并直接将其存储在那里,通过在第 3 步中传递 userId f.ex。任何参数都应该发送到第 4 步,但我没有让它工作,所以这个是我目前的做法,所以我以这种方式分享它,因为我知道它有效。