App Engine 1.3.1からJavaでも非同期URLFetchが使えるようになって、これまで悩まされ続けていた5秒タイムアウト問題が解消されつつある。
非同期URLFetchは以下のような感じ。
非同期URLFetchのサンプル
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
public class URLFetchServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
URL url = new URL("http://www.virtual-tech.net/");
URLFetchService service = URLFetchServiceFactory.getURLFetchService();
// FetchOptions.Builder. fetchOptions = new FetchOptions();
// HTTPRequest freq = new HTTPRequest(url, method);
// Future
Future
resp.getWriter().println("async fetch");
try {
HTTPResponse httpResp = asyncHttpResp.get();
resp.getWriter().println(
"content : " + httpResp.getContent());
for (HTTPHeader header : httpResp.getHeaders()) {
resp.getWriter().println(
header.getName() + ": " + header.getValue());
}
} catch (InterruptedException e) {
resp.getWriter().println(e);
} catch (ExecutionException e) {
resp.getWriter().println(e);
}
}
}
Asynchronous GData API
せっかくなので、GData APIを非同期実行できるようなパッチを作ってみた。
これは、5秒を超えて使えると思う。Google Docsで全文検索とか、Google Appsと連携とか、これまで紹介したような外部連携アプリを(やっと)本格的に作れるようになった。
ソース:
gdataclientpatch
使い方は簡単で、GoogleGDataRequest.javaとHTTPGDataRequest.javaとMediaService.javaを自分のアプリに置くだけ。(パッケージ名は変えないで)
jarについては、gdata client libにもいくつか入れているが、必要であれば、GData APIの最新版(http://gdata-java-client.googlecode.com/files/gdata-src.java-1.41.1.zip)をダウンロードして必要なjarを入れてほしい。
注意点
1.
2. GoogleDocsにはアクセス制限が存在し、1つのIPから同時に接続できるのは10程度である。アカウントを複数に別けても増えることはない。フロントエンドがリクエストIPを見てるっぽい。
3. privateでは認証が必要になるが以下のようにリトライしないとうまく取れない。
<追記>
getRequestStream()に一部不具合があったので修正しています。≧‐≦(2010/3/30)
DocsService service = null;
for (int r = 0; r < Constants.NUM_RETRIES; r++) {
try {
service = new DocsService("Google Service");
service.setUserCredentials(email, password);
logger.warning("login OK!");
return service;
} catch (ServiceException e) {
logger.warning(""+e.getStackTrace());
if (r == (Constants.NUM_RETRIES - 1)) {
return null;
}
sleep(Constants.SLEEP_MILL_SECOND);
}
}
return null;
0 件のコメント:
コメントを投稿