英文:
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<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;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论