开发者

getting strange exception trying to implement asynchronous http in google app engine for java

I'm trying to implement async http in java. Here is the important part of the code:

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())); 
} 

I keep getting this error:

com.google.apphosting.api.ApiProxy$CallNotFoundException: The API package 'urlfetch' or call 'Fetch()' was not found.

I looked around for any jars that were missing from the classpath but didn't see anything missin开发者_运维知识库g. Do you know which jar that code is in? I googled the error and also searched through this group but found nothing. Thanks, David


With Google appengine, you cannot use those api's in the local java applications. This will work only when you develop and deploy web application using google appengine sdk. This is designed to work this way only.

When you use this api, it will make use of http client and in case of app engine environment, it will make use of google infrastructure. If you still want to unit test the application designed for google appengine you might consider using LocalURLServiceFactory.


here's a simple working example of how to do this that I created for my blog:

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;

}

}

}

}


My only guess is that it's due to a Future not completing before attempting to access its response. But that's a complete and utter guess!

Maybe check each of the futureResponses .isDone() and .isCancelled() before accessing its .get().

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜