私がこれをどのように行っているかを共有します。私は 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 (サーバー)
サーバー側では、アップロード リクエスト サーブレットは次のようになります。
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 を保存し、それをクライアントに返します。ステップ4を処理するサーブレットをそのURLにマップする必要があります
ステップ 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)
createUploadUrl()
このリクエストが手順 2 でサーブレットに送信されると、前の手順で指定したサーブレットにリダイレクトされます。
ステップ 4 (サーバー)
サーバー側に戻ります。これは、 にマップされた URL を処理するサーブレットblob/upload
です。ここでは、blobkey とサービス URL を json オブジェクトでクライアントに返します。
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について
サービング URL は、その場で画像を動的にスケーリングできるため、画像をクライアントに提供する優れた方法です。たとえば=sXXX
、サービング URL の末尾に追加するだけで、小さな画像を LDPI ユーザーに送信できます。XXX は、画像の最大寸法のピクセル サイズです。インスタンスを完全に避けて帯域幅のみを支払い、ユーザーは必要なものだけをダウンロードします。
PS!
ステップ 4 で停止し、ステップ 3 で userId f.ex を渡すことにより、そこに直接保存することができるはずです。すべてのパラメーターはステップ 4 に送信されるはずですが、うまくいきませんでした。現時点でのやり方なので、うまくいくことがわかっているので、この方法で共有しています。