2013-03-16 8 views
11

Webサービスを呼び出してレスポンスを返す関数を実装する必要があります。Gwt Request builder - レスポンス文字列を返す方法

私は、Webサービスが正常に呼び出されたgetFolderJson()を呼んで

public String getFolderJson(String path) { 
      String result="initial_value"; 
      StringBuilder param = new StringBuilder(); 
      param.append("?sessionId=").append(getSessionId()); 
      param.append("&path=").append(path); 
      RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "https://localhost/folder" + param); 
        try { 
         builder.sendRequest(null, new RequestCallback() { 
         @Override 
         public void onResponseReceived(Request request, 
           Response response) { 
           result = response.getText(); 
           System.out.println(response.getText()); 
              //I need to return "result" 
         } 
         @Override 
         public void onError(Request request, Throwable exception) {} 
          }); 
        return result; //the result get returned before the response is recieved.So i am getting the return value "initial_value". 
        }  
        catch (RequestException e) {} 
     return null; 
    } 

を試してみました。しかし、respnseが受信される前にresultが返されます。だから私はretunr値 "initial_value"を得ています。
getFolderJson()が機能したときの応答から値を返す方法は?

答えて

5

GWTは同期Ajaxをサポートしていないため、非同期パターンを使用してアプリケーションをコーディングする必要があります。

GWTが要求を実行するために使用する低レベルのオブジェクトは、XMLHttpRequest(古いIEバージョンを除く)です.GWTは常に、asyncをtrueに設定してopen()メソッドを呼び出します。したがって、同期ajaxを使用する唯一の方法は、独自の修正バージョンXMLHttpRequest.javaを維持することです。しかし、同期型のajaxは悪い考えであり、jQueryでもこの可能性は推奨されていません。

gwtの通常の方法は、メソッドがvoidを返し、応答が利用可能なときに実行するコールバック付きの追加パラメータを渡すことです。

public void getFolderJson(String path, Callback<String, String> callback) { 
    RequestBuilder builder = new RequestBuilder(...); 
    try { 
     builder.sendRequest(null, new RequestCallback() { 
     @Override 
     public void onResponseReceived(Request request, Response response) { 
      callback.onSuccess(response.getText()); 
     } 
     @Override 
     public void onError(Request request, Throwable exception) {} 
      callback.onFailure(exception.getMessage()); 
     }); 
    } catch (RequestException e) { 
     callback.onFailure(exception.getMessage()); 
    } 
} 

私はむしろ代わりに要求ビルダー1のこのためPromises構文gwtqueryたい:それはより堅牢にするために

Ajax.get("http://localhost/folder?sessionId=foo&path=bar") 
    .done(new Function(){ 
     public void f() { 
     String text = arguments(0); 
     } 
    }); 
+0

私はファイルブラウザコンポーネントを持っています。コンポーネントがフォルダーの詳細を要求するときに、 'getFolderJson(...)'の結果を返す必要があります。コールバックパターンではできません。 –

+0

私はあなたのコードをコールバックを使用するように変更する方法があると信じています。それはすべてのRIAアプリケーションが動作する方法であり、たくさんの種類のアプリケーションがあります。たぶん、getFolderJsonにコールしてより大きなコードを投稿して、解決策を見つけることができるかもしれません。とにかく、同期Ajax(私が落胆させている)を使いたい場合は、 'XMLHttpRequest.java'をプロジェクトにフルパスでコピーし、' this.open(httpMethod、url、true);という行を ' 'this.open(httpMethod、url、false);' –

1

builder.sendRequest(xxx)はFutureのようなものを返してくれると思います。そのオブジェクトから結果を得ることができます。あなたが使用しているのはRequestBuilderの非同期メソッドですが、同期メソッドも必要です。

RequestBuilderは何から来ていますか?私はあなたのためにAPIをチェックすることができます。

OK、これを試してみてください。

public String getFolderJson(String path) { 
    String result = "initial_value"; 
    StringBuilder param = new StringBuilder(); 
    param.append("?sessionId=").append(getSessionId()); 
    param.append("&path=").append(path); 
    RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, 
      "https://localhost/folder" + param); 
    final SynchronousQueue resultQueue = new SynchronousQueue(); 
    try { 
     builder.sendRequest(null, new RequestCallback() { 
      @Override 
      public void onResponseReceived(Request request, 
        Response response) { 
       resultQueue.put(response.getText()); 
       System.out.println(response.getText()); 
      } 

      @Override 
      public void onError(Request request, Throwable exception) { 
      } 
     }); 
     return resultQueue.take(); 
    } catch (RequestException e) { 
    } 
    return result; 
} 

唯一のコールバックの結果を得るために任意の同期方法を持っていないRequestBuilderようです。

このメソッドは、応答が受信されるまでブロックされますので注意してください。 このメソッドがgwtのイベント処理スレッドで呼び出された場合、これは悪い習慣です。

+0

com.google.gwt.http.client.RequestBuilder –

+0

最適化を:のonError (xxx、xxx){resultQueue.put(result); }とsetTimeoutMillis(xxx)を使用してリクエストが永遠にブロックされないようにします。 – BlackJoker

+4

@ Spring.Rush 'SynchronousQueue'は、[gwt emulated jre](https://developers.google.com/web-toolkit/doc/1.6/RefJreEmulation)ではサポートされていないので、コードはjsにコンパイルされません。 –