2010-02-19 15 views
6

Sto cercando di implementare http async in java. Ecco l'importante parte del codice:ottenere strane eccezioni cercando di implementare http asincrono in google app engine per 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())); 
} 

Continuo a ricevere questo errore:

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

mi sono guardato intorno per eventuali vasetti che mancavano dal classpath, ma non ho visto nulla manca . Sai quale barattolo è inserito nel codice ? Ho cercato su Google l'errore e ho anche cercato attraverso questo gruppo ma non ho trovato nulla. David, David

risposta

8

Con Google AppEngine, non è possibile utilizzare queste API nelle applicazioni java locali. Questo funzionerà solo quando svilupperai e distribuisci applicazioni Web utilizzando google appengine sdk. Questo è progettato per funzionare solo in questo modo.

Quando si utilizza questa API, verrà utilizzato il client http e, in caso di ambiente del motore dell'app, utilizzerà l'infrastruttura di google. Se desideri ancora testare l'applicazione progettata per google appengine, potresti prendere in considerazione l'utilizzo di LocalURLServiceFactory.

0

La mia unica ipotesi è che sia dovuto a un Future non completato prima di tentare di accedere alla sua risposta. Ma questa è una supposizione completa e totale!

Forse controllare ciascuno di futureResponses.isDone() e .isCancelled() prima di accedere al suo .get().

+1

in realtà non è possibile utilizzare il contenitore del motore dell'app in un'app console. il codice funziona alla grande in una tipica configurazione del progetto del motore di app. – davidjnelson

1

Ecco un semplice esempio funzionante di come fare questo che ho creato per il mio 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; 

} 

} 

} 

} 
Problemi correlati