2010-02-19 13 views
6

Próbuję zaimplementować asynchroniczny http w java. Oto ważne część kodu:Uzyskanie dziwnego wyjątku próbującego zaimplementować asynchroniczny http w silniku aplikacji Google dla 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())); 
} 

Wciąż otrzymuję ten błąd:

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

Rozejrzałem się za słoikach, które zostały brakuje ścieżce klasy, ale nie widzę niczego brakuje . Czy wiesz, który jar jest w tym kodzie? Przeszukałem ten błąd i przeszukałem tę grupę, ale niczego nie znalazłem. Pozdrowienia, David

Odpowiedz

8

Dzięki Google App Engine, nie można korzystać z tych interfejsów API w lokalnych aplikacji java. Będzie działać tylko wtedy, gdy opracujesz i wdrożysz aplikację internetową za pomocą Google Appsengine SDK. Jest przeznaczony do pracy tylko w ten sposób.

Korzystając z tego interfejsu API, będzie on korzystał z klienta http, aw przypadku środowiska mechanizmu aplikacji użyje infrastruktury google. Jeśli nadal chcesz przetestować aplikację dla aplikacji Google, możesz rozważyć użycie LocalURLServiceFactory.

0

Przypuszczam, że jest to spowodowane niezakończeniem się Future przed próbą uzyskania dostępu do odpowiedzi. Ale to kompletna i pełna domysłów!

Może sprawdź każdy z futureResponses.isDone() i .isCancelled() przed uzyskaniem dostępu do jego .get().

+1

W rzeczywistości okazało się, że nie można używać słoju silnika aplikacji w aplikacji konsolowej. kod działa świetnie w typowej konfiguracji projektu silnika aplikacji. – davidjnelson

1

oto prosty przykład, w jaki sposób działa to, że stworzył na moim blogu zrobić:

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; 

} 

} 

} 

} 
Powiązane problemy