ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

Javaの課題丸投げコミュのAndroid端末からGAEへ画像のアップロード

  • mixiチェック
  • このエントリーをはてなブックマークに追加
はじめまして。 プログラム歴4ヶ月の新米です。
AndroidもJavaの仲間と思い、こちらに投稿させていただきました。
スレ違いでしたら削除いたします。

開発で詰まってしまったので、知恵をお貸しください。

現在、スマートフォン(Android)からサーブレット(Java)を経由してAppEngineのblobstoreに画像のアップロードを行おうと思っています。

スマホ側で
HttpPost post = new HttpPost("アップロードURL");
MultipartEntity entity = new MultipartEntity();
post.setEntity(entity);
FileBody fileBody = new FileBody(new File("filepath"));
entity.addPart("file", fileBody);
client.execute(post);

と行っているのですが、
Must only return a redirect from a Blobstore upload callback.
と返されてしまいます。

おそらく、
BlobstoreService service = BlobstoreServiceFactory.getBlobstoreService();
String uploadUrl = service.createUploadUrl("/upload");
と、uploadURLを経由していないことが原因だと思いますが、
一度、別のサーブレットで受け取り、
response.sendRedirect(uploadURL)で送っても、blobstoreにアップロードされませんでした。

どなたか、Android端末でblobstoreに画像をアップロードできる方法を教えてください。
よろしくお願いします。

コメント(4)

はじめまして。そらです。

仰るように誤解を恐れないで言えばAndroidはJavaの仲間かもしれませんが、
ご質問されているAppEngineはKVSやBlobStore等が特殊な環境なので、
少し難しい部分がありますね。

可能な範囲で回答させて頂きますと、
予測されている通り、uploadURLをBlobstoreAPIから取得していないのが問題かと思われます。

また、実装されている状況が少しわからないのですが、
リダイレクト(?)でアップロードURLの指定を試されたという事でしょうか?
リダイレクトでは純粋に指定URLへの転送なので、アップロードは無理かと思われます。

リダイレクトとフォワードの違い
http://www.atmarkit.co.jp/fjava/javatips/062jspservlet029.html

Blobstoreにファイルをアップロードする条件として、
BlobstoreAPIで発行したURLに対して、ファイルをPOSTするというのが必要になります。
アップロード先URLは経由させるのではなく、ファイルのフォワード先に指定する必要があります。

さっくり書くと流れは次のようになります。

■サーバ
//1.BlobstoreAPIでアップロード先URLの発行
BlobstoreService service = BlobstoreServiceFactory.getBlobstoreService();
String uploadUrl = service.createUploadUrl("/upload");

//2.クライアントにアップロード先URLを渡す(セッションでもリクエストでも可)
//クライアント表示(フォワード等)

--

■クライアント
<%-- 3.サーバから受け取ったURLをactionに指定してファイルをアップロード(enctypeはマルチパートを指定する) --%>

<form action="<%= uploadURL %>" method="post" enctype="multipart/form-data">
<%-- ファイルをアップロード --%>
<input type="file" name="hoge"/>
<input type="submit" value="up"/>
</form>

という形になります。
申し訳ないですがAndroidの方は確認しないと分からないので、
HTMLの例で記載させて頂いています。
そら様
さっそくのご解答ありがとうございます。
御察しのとおり、リダイレクトでアップロード先URLの指定を行っただけです。

>リダイレクトとフォワードの違い
>http://www.atmarkit.co.jp/fjava/javatips/062jspservlet029.html

大変参考にさせていただきました。
リクエスト情報も送信できるとなると、まさに目からうろこです。。。

一応、blobstoreにアップロードは行えたのですが
送信を行う前に、Android端末からサーブレットにuploadURLの文字列を下さいというリクエストを送信し、
そのURLを受け取り、画像をPOSTを行うという形です。
このプログラムだと、画像1枚につき通信が2回発生してしまい、
クラウドを利用している上ではいい設計とはいえないと思っています。

なので、現在、行いたい事としましては、
Android端末からPOST通信によって送信された画像をサーブレット側で受け取り、
サーブレットがアップロードURLにPOSTを行うことです。

そら様の情報と混ぜて作り上げましたが、それも上手くいきませんでした。

■Android側
HttpPost post = new HttpPost("サーブレット1");
MultipartEntity entity = new MultipartEntity(); //multipart/form-dataの設定
post.setEntity(entity);
FileBody fileBody = new FileBody(new File("filepath"));
entity.addPart("file", fileBody);
client.execute(post);

■サーブレット1
BlobstoreService blobs = BlobstoreServiceFactory.getBlobstoreService();
String uploadUrl = blobs.createUploadUrl("/upload");
RequestDispatcher dispatch = req.getRequestDispatcher(uploadUrl);
dispatch.forward(req, resp);


泥沼にはまってしまっています。。。
ご教授お願いします。
そらです。

以下少しBlobstoreの概念に踏み込んだ内容となります。
こちらで書くには限界がありますので、
あまり馴染みがないようでしたら、一度Blobstoreの概念を確認頂いた方が良いかもしれません。
http://code.google.com/intl/ja/appengine/docs/java/blobstore/overview.html

>一応、blobstoreにアップロードは行えたのですが
>送信を行う前に、Android端末からサーブレットにuploadURLの文字列を下さいというリクエストを送信し、
>そのURLを受け取り、画像をPOSTを行うという形です。
>このプログラムだと、画像1枚につき通信が2回発生してしまい、
>クラウドを利用している上ではいい設計とはいえないと思っています。
実施されたい事は
Android上のローカル環境に設置したWebView等からサーブレットを介してアップロードする
ような事でしょうか?

申し訳ないですが、Blobstoreの設計思想上、
サーブレットを介してBlobデータをやり取りするというのがないので、
私は試した事がありません。

Blobstoreは、リクエストからデータを取り出したものをBlobstoreに格納し、
リクエストを書き換え、処理をアップロード制御ハンドラに引き渡します。
このアップロード制御ハンドラとは、アップロード先URL生成時に指定するURLです。
No2.の場合、/uploadとマッピングされているServletとなります。

もしNo2.で試されているやり方で実施されるのであれば、
一度サーブレット1の時点でデータを受け取れているか確認されて見ると良いと思います。


また、余談となりますが、
アップロード先のURL情報の受け渡しだけであれば文字列のデータがやりとりされるだけですが、
No2でされているように画像等のバイナリデータをサーブレットに送信した後、Blobstoreに送信するとなると、
通信量は後者の方が多いかと思われます。

GAEはFrontend Instance等リソース使用量を監視しておりますので、
むやみにサーブレットでデータを中継するのはあまり良い処理ではないと思います。
アップロードが対サーブレットの場合、GAEの定めるQuotaの影響により、
ファイル容量次第ではアップロードが出来ない場合も出てきます。

つきましては、上記No2のやり方で上手く出来たとしても、
あまりお勧め出来ないと言うのが個人的な意見です。
そら様。
度々の解答まことにありがとうございます。

見慣れない言葉も多々あり、勉強不足を痛感しています。


>実施されたい事は
>Android上のローカル環境に設置したWebView等からサーブレットを介してアップロードする
>ような事でしょうか?
大方そのとおりです。Androidのデータベースをクラウドで同期を行うようなものです。

POSTされた情報をサーブレット1で確認した所、Nullでした。
原因がわからないのでもう少し調査したいと思います。

余談の話。
本当にありがとうございます。
現行のやりかたで、uploadURLをプリファレンスに保存し、以降はそれを使いまわす事にします。

色々とご迷惑をおかけしました。
なるべく自己の力で解決を行う事を心がけていますが、
行き詰ってしまったときにまた、投稿させていただくかもしれません。
その時はまたよろしくお願いします。


そら様。ありがとうございました。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

Javaの課題丸投げ 更新情報

Javaの課題丸投げのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング