Sure, here’s the translation: 你可以使用OkHttp的enqueue方法返回响应吗?

huangapple go评论61阅读模式
英文:

Can you return a response using OkHttp's enqueue method?

问题

我目前使用一个普通的 newCall(Request).execute(),就像 Okio 的一个示例中所解释的那样,但我更希望使用它们的 enqueue 方法来执行异步操作。

然而,我面临的问题是,我必须返回一个从请求的响应中生成的字符串。

对于 execute 方法,目前是这样的:

public class HttpUtil{
    private final OkHttpClient CLIENT = new OkHttpClient();

    public HttpUtil(){}

    public String getImage(String url) throws IOException{
        Request request = new Request.Builder()
                .url(url)
                .build();

        try(Response response = CLIENT.newCall(request).execute()){
            if(!response.isSuccessful())
                throw new IOException(String.format(
                        "Unexpected code from url %s: %s",
                        url,
                        response
                ));

            ResponseBody body = response.body();
            if(body == null)
                throw new NullPointerException("Received empty body!");

            String bodyString = body.string();
            if(bodyString.isEmpty())
                throw new NullPointerException("Received empty body!");

            return new JSONObject(bodyString).getString("link");
        }
    }
}

从上面的方法中,您可以看到我使用返回的响应体作为字符串生成了一个新的 JSONObject,然后获取了字段值 "link"。

现在是否有任何方法在使用 enqueue 方法的同时仍然可以返回一个字符串呢?

英文:

I currently use a normal newCall(Request).execute() as explained in one of Okio's examples, but I would prefer to use their enqueue method to have the action performed be async.

The issue I face however is the fact, that I have to return a String, which is generated from the response of the request.

In the case of the execute method does it look like this right now:

public class HttpUtil{
    private final OkHttpClient CLIENT = new OkHttpClient();

    public HttpUtil(){}
    
    public String getImage(String url) throws IOException{
        Request request = new Request.Builder()
                .url(url)
                .build();

        try(Response response = CLIENT.newCall(request).execute()){
            if(!response.isSuccessful())
                throw new IOException(String.format(
                        "Unexpected code from url %s: %s",
                        url,
                        response
                ));
            
            ResponseBody body = response.body();
            if(body == null)
                throw new NullPointerException("Received empty body!");
            
            String bodyString = body.string();
            if(bodyString.isEmpty())
                throw new NullPointerException("Received empty body!");
            
            return new JSONObject(bodyString).getString("link");
        }
    }
}

From the above method can you see that I generate a new JSONObject using the returned body as String and then get the field value of "link".

Is there now any way I could still return a String, while using the enqueue method?

答案1

得分: 2

public class HttpUtil {
  private final OkHttpClient CLIENT = new OkHttpClient();

  public Future<String> getImage(String url) throws IOException {
    Request request = new Request.Builder()
      .url(url)
      .build();

    CompletableFuture<String> f = new CompletableFuture<>();

    CLIENT.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
          f.completeExceptionally(e);
        }

        @Override
        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
          if (!response.isSuccessful())
            throw new IOException(String.format(
              "Unexpected code from url %s: %s",
              url,
              response
            ));

          String bodyString = response.body().string();
          
          f.complete(new JSONObject(bodyString).getString("link"));
        }
      }
    );
    
    return f;
  }
}
英文:

Return a Future<String> so you are actually doing async programming, otherwise it's a pointless exercise to complicate the code using async methods while try to keep your simple sync method.

public class HttpUtil {
  private final OkHttpClient CLIENT = new OkHttpClient();

  public Future&lt;String&gt; getImage(String url) throws IOException {
    Request request = new Request.Builder()
      .url(url)
      .build();

    CompletableFuture&lt;String&gt; f = new CompletableFuture&lt;&gt;();

    CLIENT.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NotNull Call call, @NotNull IOException e) {
          f.completeExceptionally(e);
        }

        @Override
        public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
          if (!response.isSuccessful())
            throw new IOException(String.format(
              &quot;Unexpected code from url %s: %s&quot;,
              url,
              response
            ));

          String bodyString = response.body().string();
          
          f.complete(new JSONObject(bodyString).getString(&quot;link&quot;));
        }
      }
    );
    
    return f;
  }
}

huangapple
  • 本文由 发表于 2020年8月21日 23:53:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63526126.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定