получая странное исключение при попытке реализовать асинхронный http в google app engine для java - PullRequest
7 голосов
/ 20 февраля 2010

Я пытаюсь реализовать асинхронный http в Java.Вот важная часть кода:

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

Я получаю эту ошибку:

com.google.apphosting.api.ApiProxy $ CallNotFoundException: пакет API 'urlfetch'или вызов' Fetch () 'не был найден.

Я осмотрел все банки, которые отсутствовали в пути к классам, но ничего не увидел.Вы знаете, в каком банке находится этот код?Я погуглил ошибку, а также искал в этой группе, но ничего не нашел.Спасибо, Дэвид

Ответы [ 3 ]

8 голосов
/ 25 января 2011

С помощью Google appengine вы не можете использовать эти API в локальных Java-приложениях.Это будет работать только при разработке и развертывании веб-приложения с помощью Google Appengine SDK.Это предназначено для работы только таким способом.

Когда вы используете этот API, он будет использовать http-клиент, а в случае среды ядра приложения - инфраструктуру Google.Если вы все еще хотите выполнить модульное тестирование приложения, разработанного для Google Appengine, вы можете рассмотреть возможность использования LocalURLServiceFactory.

1 голос
/ 11 марта 2010

Вот простой рабочий пример того, как я это сделал для своего блога:

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;

}

}

}

}
0 голосов
/ 20 февраля 2010

Мое единственное предположение, что это из-за того, что Future не завершился, прежде чем пытаться получить доступ к его ответу.Но это полное и полное предположение!

Возможно, проверьте каждый из futureResponses .isDone() и .isCancelled(), прежде чем получить доступ к его .get().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...