正如Okio的一个例子中所解释的,我目前使用普通的newCall(Request).execute()
,但我更喜欢使用他们的enqueue
方法,以使执行的操作是异步的。
然而,我面临的问题是,我必须返回一个String,它是根据请求的响应生成的。
在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");
}
}
}
从上面的方法可以看出,我使用返回的body作为String生成了一个新的JSONObject,然后得到字段值";链接";。
现在,在使用enqueue方法时,是否有任何方法可以返回String?
返回一个Future,这样您实际上是在进行异步编程,否则,在保持简单同步方法的同时,使用异步方法使代码复杂化是毫无意义的。
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;
}
}