尝试在google app engine for java中实现异步http时出现异常
我正在尝试用java实现异步http。这是重要的问题 守则的一部分:尝试在google app engine for java中实现异步http时出现异常,java,http,google-app-engine,Java,Http,Google App Engine,我正在尝试用java实现异步http。这是重要的问题 守则的一部分: for (String urlString : urls) { // TODO: try and get rid of these two heap allocations url = new URL(urlString); request = new HTTPRequest(url); request.addHeader(userAgentHeader); request.
for (String urlString : urls)
{
// TODO: try and get rid of these two heap allocations
url = new URL(urlString);
request = new HTTPRequest(url);
request.addHeader(userAgentHeader);
request.addHeader(authorizationHeader);
request.addHeader(acceptEncodingHeader);
request.addHeader(acceptCharsetHeader);
responses.add(URLFetchServiceFactory.getURLFetchService().fetchAsync(reques t));
apiCallsMade++;
}
for (Future<HTTPResponse> futureResponse : responses)
{
parseResponse(new String(futureResponse.get().getContent()));
}
for(字符串urlString:url)
{
//TODO:尝试摆脱这两个堆分配
url=新url(url字符串);
请求=新的HTTPRequest(url);
addHeader(userAgentHeader);
request.addHeader(authorizationHeader);
request.addHeader(acceptEncodingHeader);
request.addHeader(acceptCharsetHeader);
add(URLFetchServiceFactory.getURLFetchService().fetchAsync(requues t));
apiCallsMade++;
}
对于(未来响应:响应)
{
parseResponse(新字符串(futureSponse.get().getContent());
}
我不断地发现这个错误:
ApiProxy$CallNotFoundException:api包“urlfetch”或调用“Fetch()”的
找不到
我环顾四周,看看有没有什么罐子从窗户上掉了下来
类路径,但没有发现缺少任何内容。你知道哪个罐子吗
那个密码在哪?我用谷歌搜索了错误,也搜索了这个
但没有发现任何东西。
谢谢
David我唯一的猜测是,这是由于一个
未来
在尝试访问其响应之前没有完成。但这完全是猜测
在访问其
.get()
之前,可能会检查每个未来响应
.isDone()和.isCancelled()
,下面是一个简单的工作示例,说明如何执行此操作,我为我的博客创建了此操作:
package org.appEngineAsync.server;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;
import org.appEngineAsync.client.GreetingService;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements GreetingService
{
private HTTPRequest request = null;
HTTPHeader acceptCharsetHeader = new HTTPHeader("Accept-Charset", "utf-8");
// All three of these data types are synchronized for thread safety
List<Future<HTTPResponse>> responses = new CopyOnWriteArrayList<Future<HTTPResponse>>();
protected List<String> tempSingleUrl = new CopyOnWriteArrayList<String>();
StringBuffer sb = new StringBuffer();
public String greetServer(String input) throws Exception
{
List<String> urlsToFetchInParrallel = new ArrayList<String>();
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=1&max-results=10&v=2");
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=11&max-results=10&v=2");
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=21&max-results=10&v=2");
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=31&max-results=10&v=2");
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=41&max-results=10&v=2");
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=51&max-results=10&v=2");
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=61&max-results=10&v=2");
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=71&max-results=10&v=2");
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=81&max-results=10&v=2");
urlsToFetchInParrallel.add("http://gdata.youtube.com/feeds/api/channels?q=" + input + "&start-index=91&max-results=10&v=2");
return performHttpRequest(urlsToFetchInParrallel);
}
// pass in 10 urls at a time
private final String performHttpRequest(List<String> urls) throws NumberFormatException, Exception
{
URL url = null;
request = null;
byte[] tempBuffer = null;
byte[] buffer = null;
ByteArrayInputStream memoryStream = null;
ByteArrayOutputStream baos = null;
final int buffSize = 8192;
int size = 0;
sb.setLength(0);
responses.clear();
try
{
for (String urlString : urls)
{
url = new URL(urlString);
request = new HTTPRequest(url);
request.addHeader(acceptCharsetHeader);
responses.add(URLFetchServiceFactory.getURLFetchService().fetchAsync(request));
}
for (Future<HTTPResponse> futureResponse : responses)
{
try
{
memoryStream = new ByteArrayInputStream(futureResponse.get().getContent());
tempBuffer = new byte[buffSize];
baos = new ByteArrayOutputStream();
while ((size = memoryStream.read(tempBuffer, 0, buffSize)) != -1)
{
baos.write(tempBuffer, 0, size);
}
buffer = baos.toByteArray();
} catch (Exception ex)
{
// TODO: log or take other action
return null;
} finally
{
try
{
baos.close();
} catch (Exception ex)
{
// TODO: log
}
}
// TODO: put this on one line when done debugging
String responseString = new String(buffer, "UTF-8");
sb.append(responseString);
}
// TODO: put this on one line when done debugging
String allResponsesString = sb.toString();
return allResponsesString;
} catch (Exception ex)
{
// TODO: log
return null;
} finally
{
try
{
request = null;
url = null;
memoryStream = null;
tempBuffer = null;
baos = null;
} catch (Exception ex)
{
// TODO: log
return null;
}
}
}
}
package org.appEngineAsync.server;
导入java.io.ByteArrayInputStream;
导入java.io.ByteArrayOutputStream;
导入java.net.URL;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.CopyOnWriteArrayList;
导入java.util.concurrent.Future;
导入org.appEngineAsync.client.GreetingService;
导入com.google.appengine.api.urlfetch.HTTPHeader;
导入com.google.appengine.api.urlfetch.HTTPRequest;
导入com.google.appengine.api.urlfetch.HTTPResponse;
导入com.google.appengine.api.urlfetch.URLFetchServiceFactory;
导入com.google.gwt.user.server.rpc.RemoteServiceServlet;
@抑制警告(“串行”)
公共类GreetingServiceImpl扩展RemoteServiceServlet实现GreetingService
{
私有HTTPRequest请求=null;
HTTPHeader acceptCharsetHeader=新的HTTPHeader(“AcceptCharset”,“utf-8”);
//为了线程安全,这三种数据类型都是同步的
列表响应=新建CopyOnWriteArrayList();
受保护列表tempSingleUrl=新建CopyOnWriteArrayList();
StringBuffer sb=新的StringBuffer();
公共字符串greetServer(字符串输入)引发异常
{
List urlstofetchinparallel=new ArrayList();
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+input+”&start index=1&max results=10&v=2”);
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+输入+”&开始索引=11&最大结果=10&v=2”);
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+输入+”&开始索引=21&最大结果=10&v=2”);
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+输入+”&开始索引=31&最大结果=10&v=2”);
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+输入+”&开始索引=41&最大结果=10&v=2”);
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+输入+”&开始索引=51&最大结果=10&v=2”);
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+输入+”&开始索引=61&最大结果=10&v=2”);
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+输入+”&开始索引=71&最大结果=10&v=2”);
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+输入+”&开始索引=81&最大结果=10&v=2”);
UrlsToFetchInParallel.add(“http://gdata.youtube.com/feeds/api/channels?q=“+输入+”&开始索引=91&最大结果=10&v=2”);
返回performHttpRequest(URLSTOFETCHINPRALLEL);
}
//一次传入10个URL
私有最终字符串performHttpRequest(列出URL)引发NumberFormatException,异常
{
URL=null;
请求=null;
字节[]tempBuffer=null;
字节[]缓冲区=空;
ByteArrayInputStream memoryStream=null;
ByteArrayOutputStream baos=null;
最终尺寸=8192;
int size=0;
sb.设定长度(0);
回答:clear();
尝试
{
用于(字符串URL:URL)
{
url=新url(url字符串);
请求=新的HTTPRequest(url);
request.addHeader(acceptCharsetHeader);
add(URLFetchServiceFactory.getURLFetchService().fetchAsync(请求));
}
对于(未来响应:响应)
{
尝试
{
memoryStream=newbytearrayinputstream(futuresponse.get().getContent());
tempBuffer=新字节[buffSize];
bas=新的ByteArrayOutputStream();
while((size=memoryStream.read(tempBuffer,0,buffSize))!=-1)
{
写入(tempBuffer,0,大小);
}
buffer=baos.toByteArray();
}捕获(例外情况除外)
{
//TODO:记录或执行其他操作
返回null;
}最后
{
尝试
{
baos.close();
}捕获(例外情况除外)
{
//TODO:日志
}
}
//TODO:调试完成后将其放在一行
字符串响应字符串=新字符串(缓冲区,“UTF-8”);
某人追加(职责);
}
//TODO:调试完成后将其放在一行
字符串allresponseString=sb.toString();
返回所有responseString;
}捕获(例外情况除外)
{
//TODO:日志
返回null;
}最后
{
尝试
{
请求=null;
url=null;
memoryStream=null;
tempBuffer=null;
baos=null;
}捕获(例外情况除外)
{
//TODO:日志
返回null;
}
}
}
}
使用Google appengine,您无法在本地java应用程序中使用这些api。只有当您使用google appengine sdk开发和部署web应用程序时,这才有效。这是专为这种方式工作
当您使用此api时,它将使用http客户端,在应用程序引擎环境中,它将使用google基础设施。如果您仍然想对为GoogleAppEngine设计的应用程序进行单元测试,您可能会考虑