2010-06-07 4 views
0

J'écris un simple service Google Web Toolkit qui agit comme un proxy, qui existera essentiellement pour permettre au client de faire un POST à ​​un serveur différent. Le client utilise essentiellement ce service pour demander un appel HTTP. Le service a un seul appel de méthode asynchrone, appelé ajax(), qui devrait simplement transmettre la réponse du serveur. Mon code pour la mise en œuvre de l'appel ressemble à ceci:Google Web Toolkit Appel asynchrone à partir d'une mise en œuvre de service

class ProxyServiceImpl extends RemoteServiceServlet implements ProxyService { 
    @Override 
    public Response ajax(String data) { 
     RequestBuilder rb = /*make a request builder*/ 
     RequestCallback rc = new RequestCallback() { 
      @Override 
      public void onResponseReceived(Response response) { 
       /* Forward this response back to the client as the return value of 
        the ajax method... somehow... */ 
      } 
     }; 
     rb.sendRequest(data, requestCallback); 
     return /* The response above... except I can't */; 
    } 
} 

Vous pouvez voir la forme de base de mon problème, bien sûr. La méthode ajax() est utilisée de manière asynchrone, mais GWT décide d'être intelligent et de cacher cela à l'ancien développeur bête, afin qu'il puisse écrire du code Java normal sans callback. Les services GWT font simplement de la magie au lieu d'accepter un paramètre de rappel.

Le problème se pose alors, car GWT cache de moi l'objet de rappel. J'essaie de faire mon propre appel asynchrone à partir de l'implémentation du service, mais je ne peux pas, car les services GWT supposent que vous vous comportez de manière synchrone dans les implémentations de service. Comment puis-je contourner ce problème et effectuer un appel asynchrone à partir de ma mise en œuvre de la méthode de service?

+0

Juste pour vérifier - vous voulez que la méthode ajax se bloque jusqu'à ce que votre sendRequest asynchrone soit terminée, puis renvoyez ce résultat - oui? Vous avez deux appels asynchrones, un du client gwt au serveur gwt via rpc, et un autre appel asynchrone du serveur gwt à votre serveur externe - non? –

+0

Oui, c'est fondamentalement correct –

Répondre

3

Vous mélangez le code côté client et serveur. Dans ProxyServiceImpl, vous ne pouvez pas utiliser RequestBuilder. RequestBuilder est une classe côté client qui ne s'exécutera que dans le navigateur. Un appel http de serveur à serveur est toujours synchrone. Au lieu d'utiliser RequestBuilder, vous devriez utiliser une bibliothèque comme HttpClient, obtenir les résultats, puis le renvoyer au client. Cela résoudrait le problème auquel vous êtes confronté.

Mais je devrais ajouter, vous ne voulez pas construire un proxy au niveau de l'application. Vous pouvez tout aussi bien utiliser un proxy http tel que apache's mod_proxy.

+0

Ah, vous avez raison dans ce cas précis. J'aimerais quand même savoir en général comment vous traiteriez un second appel asynchrone à partir de l'implémentation du service. (Impossible d'utiliser mod_proxy parce que c'est sur App Engine). –

+0

Si vous êtes sur GAE, vous devrez utiliser 'java.net.URL' pour faire vos demandes,' httpclient' n'est pas supporté. –

+0

En général, il est difficile de gérer un second appel asynchrone, car vous devez immédiatement envoyer une réponse au client. Vous pourriez générer un thread et mettre du code de synchronisation, mais cela ne fonctionnerait pas encore dans GAE. La seule autre façon est d'envoyer un handle dans la première réponse, puis de faire une deuxième requête http après un certain temps pour obtenir les données réelles. Si vous en avez vraiment, vraiment, vraiment besoin, faites plusieurs requêtes http. –