fc2ブログ

【GoogleAppEngine】サーブレット処理内のデータをBlobstoreに登録する【BlobstoreService】【FileService】【URLFetch】

2012-01-11 02:17:17 Wed

■サーブレット処理内のデータをBlobstoreに登録する


前回記事の延長です。
やりたかったことは、リクエストパラメータで指定された外部URLを受け取り、
これをURLFetchして外部のバイナリデータを取得。
そして取得したバイナリデータをBlobstoreに格納すること。

これができそうで出来なくて困りましたが、結論、できます。
ただし、「experimental」がマークされており、2012/01/11 02:07:22現在、APIが廃止、互換性のない大幅変更される可能性もあります。

なお、参考にしたのは次のURLになります。

●参考
http://webcache.googleusercontent.com/search?q=cache:7UvAdoWK03kJ:d.hatena.ne.jp/knj77/20110414/1302781605+blobstore%E3%80%80%E7%9B%B4%E6%8E%A5%E4%BF%9D%E5%AD%98&cd=2&hl=ja&ct=clnk&gl=jp
http://d.hatena.ne.jp/a-know/20120105/1325764373
http://code.google.com/intl/en/appengine/docs/java/blobstore/overview.html#Writing_Files_to_the_Blobstore
http://www.programminglife.jp/2011/03/blobstore.html

■実装方法


単純な実装をしたので簡単にポイントをメモ。

URLFetchService service = URLFetchServiceFactory.getURLFetchService();
HTTPResponse res = service.fetch(new URL((String)map.get("filename")));
registBlob(res.getContent());


これはただURLFetchServiceを介して外部URLの画像ファイル(とは本来限らないが…)を取得しに行っています。

private BlobKey registBlob(byte[] bytes) throws IOException{
// Get a file service
FileService fileService = FileServiceFactory.getFileService();
// Create a new Blob file with mime-type "application/octet-stream"
AppEngineFile file = fileService.createNewBlobFile("image/jpeg");
// Open a channel to write to it
boolean lock = true;
FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
// This time we write to the channel using standard Java
writeChannel.write(ByteBuffer.wrap(bytes));
// Now finalize
writeChannel.closeFinally();
return fileService.getBlobKey(file);
}


URLFetchServiceを介して取得した画像ファイル(画像ファイルと言いたければ、レスポンスヘッダを検証すべきだが…)のバイト配列を取得し、これをメソッドの第一引数として受け取り、
FileServiceを介してBlobstoreにバイナリデータを登録しています。
別に画像と限る必要はなく、ZIP圧縮したファイル、シリアライズしたクラスなどバイナリデータならなんでも格納できます。
FileWriteChannel#writeメソッドの引数にはjava.nioのByteBufferクラスを渡しています。

■サンプル




import java.io.IOException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;
import org.slim3.util.RequestMap;

import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.google.appengine.api.files.AppEngineFile;
import com.google.appengine.api.files.FileService;
import com.google.appengine.api.files.FileServiceFactory;
import com.google.appengine.api.files.FileWriteChannel;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;

public class UploadExternalUrlController extends Controller {

@Override
public Navigation run() throws Exception {

RequestMap map = new RequestMap(request);
URLFetchService service = URLFetchServiceFactory.getURLFetchService();
HTTPResponse res = service.fetch(new URL((String)map.get("filename")));
registBlob(res.getContent());

BlobstoreService bservice = BlobstoreServiceFactory.getBlobstoreService();
String uploadUrl = bservice.createUploadUrl("/test/Upload");
BlobInfoFactory factory = new BlobInfoFactory();
List blobs = new ArrayList();
Iterator ite = factory.queryBlobInfos();
while(ite.hasNext()){
blobs.add(ite.next());
}
requestScope("upload_url", uploadUrl);
requestScope("blobs", blobs);
return forward("DataManager.vm");
}

private BlobKey registBlob(byte[] bytes) throws IOException{
// Get a file service
FileService fileService = FileServiceFactory.getFileService();
// Create a new Blob file with mime-type "application/octet-stream"
AppEngineFile file = fileService.createNewBlobFile("image/jpeg");
// Open a channel to write to it
boolean lock = true;
FileWriteChannel writeChannel = fileService.openWriteChannel(file, lock);
// This time we write to the channel using standard Java
writeChannel.write(ByteBuffer.wrap(bytes));
// Now finalize
writeChannel.closeFinally();
return fileService.getBlobKey(file);
}

}



⇒comment

Secret

名言集
全記事(数)表示
全タイトルを表示
ブログ内検索
Loading