2010-02-19 5 views
6

J'essaie d'implémenter async http en Java. Voici l'importante partie du code:obtenir étrange exception en essayant d'implémenter http asynchrone dans le moteur de l'application google pour 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())); 
} 

Je continue à obtenir cette erreur:

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

Je cherchai des pots qui ont été absents de la classpath, mais n'a pas vu quelque chose qui manque . Savez-vous quel pot ce code est? J'ai googlé l'erreur et j'ai aussi cherché dans ce groupe mais je n'ai rien trouvé. Merci, David

Répondre

8

Avec Google AppEngine, vous ne pouvez pas utiliser ces api est dans les applications Java locales. Cela fonctionne uniquement lorsque vous développez et déployez une application Web à l'aide de google appengine sdk. Ceci est conçu pour fonctionner de cette façon seulement. Lorsque vous utiliserez cette API, il utilisera le client http et dans le cas d'un environnement de moteur d'application, il utilisera l'infrastructure google. Si vous souhaitez tester l'application conçue pour google appengine, vous pouvez envisager d'utiliser LocalURLServiceFactory.

0

Ma seule supposition est que c'est dû à Future ne pas terminer avant d'essayer d'accéder à sa réponse. Mais c'est une supposition complète et totale!

Peut-être vérifier chacun des futureResponses.isDone() et .isCancelled() avant d'accéder à son .get().

+1

En fait, il s'est avéré que vous ne pouvez pas utiliser le jar du moteur de l'application dans une application de console. le code fonctionne très bien dans une configuration de projet de moteur d'application typique. – davidjnelson

1

est ici un exemple simple de travail de la façon de faire ce que j'ai créé pour mon 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; 

} 

} 

} 

} 
Questions connexes