2017-02-17 15 views
0

私はSpringブートでweb-appを持っています。また、多くのHTTPリクエストをAPIに渡す部分があり、リクエストが多すぎるとタイムアウトしているようです。同期の要求から非同期の要求への切り替えがこの問題に役立つかもしれないと聞きました。 OkHttpを使用してJava - OkHttpからの結果の取得非同期GET

、これは私の同期GETリクエストは次のようになります。

private JSONObject run(String url) throws Exception { 
    Request newRequest = new Request.Builder() 
      .url(url) 
      .addHeader("Authorization", token) 
      .build(); 

    try (Response response = client.newCall(newRequest).execute()) { 
     if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 
     return new JSONObject(response.body().string()); 

    } 
} 

私はレスポンスボディを解析からJSONオブジェクトとして応答を返します。しかし、OkHttp非同期呼び出しを使用しようとして、私は同じアプローチを使用することはできないようです。これは私がこれまで持っているものです。

public void runAsync(String url) throws Exception { 
    Request request = new Request.Builder() 
      .url(url) 
      .addHeader("Authorization", token) 
      .build(); 

    client.newCall(request).enqueue(new Callback() { 
     @Override public void onFailure(Call call, IOException e) { 
      e.printStackTrace(); 
     } 

     @Override public void onResponse(Call call, Response response) throws IOException { 
      if (!response.isSuccessful()) throw new IOException("Unexpected code " + response); 

      System.out.println(response.body().string()); 
     } 
    }); 
} 

応答は、ボイドの戻り値を持つコールバックメソッドの内部でラップされているように私は単純に、JSONとして結果を返すことができません。応答を抽出する私の同期GETに似た結果を得る方法についてのアイデアはありますか?

+0

これは実際に非同期呼び出しに変更するメリットはありません。理想的には、あなたのことを呼び出すWebフレームワークにFuture のようなものを返し、将来の完了を非同期的に処理します。 完了した結果を呼び出し元に返す必要がある場合は、その呼び出しが同期呼び出しになるかどうかにかかわらず、1つの要求を作成する必要があります。 もう1つの可能性は、最終結果が多くの要求に依存することです。その場合、それらを同時に実行すると同時に実行すると助けになります。 –

+0

興味深いことに私の場合、すべての結果を解析して集約し、内容を文字列に格納するという目的で、多くのHTTP要求が行われています。それは同期のように聞こえる同時並行要求は私がする必要があるかもしれません。この非同期メソッドを私の問題に適していないだろうか? –

+0

実際はまだ理想的ですね。非同期タスクで同時にデータをフェッチし、同時に解析し、個々の結果がすべて完了するまで同期してブロックすることができます。 –

答えて

2

私はSpring Bootのユーザーではないので、これは完全な答えではありません。しかし、それが未来を返すことをサポートすれば、OkHttpコールバックから未来への橋渡しは簡単です。

これが関連する可能性があるhttps://spring.io/guides/gs/async-method/

public class OkHttpResponseFuture implements Callback { 
    public final CompletableFuture<Response> future = new CompletableFuture<>(); 

    public OkHttpResponseFuture() { 
    } 

    @Override public void onFailure(Call call, IOException e) { 
    future.completeExceptionally(e); 
    } 

    @Override public void onResponse(Call call, Response response) throws IOException { 
    future.complete(response); 
    } 
} 

そして未来を製造するようエンキューあなたがそれらを提出することができます処理するために複数の要求がある場合

OkHttpResponseFuture callback = new OkHttpResponseFuture(); 
    client.newCall(request).enqueue(callback); 

    return callback.future.thenApply(response -> { 
    try { 
     return convertResponse(response); 
    } catch (IOException e) { 
     throw Throwables.propagate(e); 
    } finally { 
     response.close(); 
    } 
    }); 

ような仕事何か別々にしてから、すべての結果が利用可能になるのを待ってから組み合わせて返信してください。

public static <T> CompletableFuture<List<T>> join(List<CompletableFuture<T>> futures) { 
    CompletableFuture[] cfs = futures.toArray(new CompletableFuture[futures.size()]); 

    return CompletableFuture.allOf(cfs) 
     .thenApply(v -> combineIndividualResults(c)); 
    } 
関連する問題