java应用程序引擎URL获取回调
我对应用程序引擎比较陌生。我不明白如何用Java异步发出HTTP请求。我本以为使用Thread和Runnable是一件非常简单的事情。但似乎appengine不允许使用它们
public Hashtable someApiMethod(..) {
SomeEntity entity = new SomeEntity(..);
ObjectifyService.ofy().save().entity(entity).now();
makeSomeHttpRequest(entity);
return launchResponse;
}
我的问题是:如何实现makeSomeHttpRequest(…)方法这样它就可以在不等待URLFetchService的情况下返回。fetchAsync返回。我尝试了以下方法,但没有成功:
protected void makeSomeHttpRequest(SomeEntity entity) {
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
try {
URL url = new URL("https://www.example.com");
Future future = fetcher.fetchAsync(url);
HTTPResponse response = (HTTPResponse) future.get();
byte[] content = response.getContent();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(content);
String responseString = new String(bos.toByteArray());
int responseCode = response.getResponseCode();
// Here I will do something with the responseCode and responseString
if (responseCode == 200) entity.someValue = responseString;
} catch (IOException e) {
// handle this
} catch (InterruptedException e) {
// handle this
} catch (ExecutionException e) {
// handle this
}
}
实际上,我试图做的是执行这个HTTP请求,而不强制方法someApiMethod等待响应
# 1 楼答案
几件事:
首先
Future
不是这样工作的。方法.get
等待特性执行的结果,所以基本上您正在停止当前线程,直到其他线程完成其执行。你让它同步,这没有任何意义。通常,当当前线程中的所有其他工作完成时,您会在很久以后调用.get
第二。Appengine中的线程仅限于当前请求,您必须在当前请求期间完成所有异步处理。因此,以这种方式更新实体没有多大意义,它仍然受限于当前请求。我的意思是在你的情况下
makeSomeHttpRequest(entity);
应该比return launchResponse;
快您真正需要的是将此数据发送到任务队列,并从那里对
SomeEntity entity
进行处理(但不发送实体本身,只发送ID并按ID从队列任务加载)。基本上,它将是一个新的请求处理程序(servlet/controller/etc),它应该按id加载实体,执行makeSomeHttpRequest
(同步)并返回http状态200请参阅TaskQueue文档:https://cloud.google.com/appengine/docs/java/taskqueue/
您很可能需要推送队列:https://cloud.google.com/appengine/docs/java/taskqueue/overview-push