猿问

返回 OkHttp 异步结果有问题

我有一个java SDK,它使用OkHttp客户端(4.0.0)从服务器获取令牌IAM并将令牌返回给应用程序。关系可能是这样的:Applicaiton Sync call SDKSDKAsync call IAM。参考这个答案Java - Retrieving Result from OkHttpAsynchronous GET,the代码如下:

异步类:


class BaseAsyncResult<T> {

private final CompletableFuture<T> future = new CompletableFuture<>();


T getResult() {

    try {

        return future.get();

    } catch (InterruptedException | ExecutionException e) {

        e.printStackTrace();

    }

    return null;

}


void onFailure(IOException e) {

    future.completeExceptionally(e);

}


void onResponse(Response response) throws IOException {

    String bodyString = Objects.requireNonNull(response.body()).string();

    future.complete(IasClientJsonUtil.json2Pojo(bodyString, new TypeReference<T>() {}));

}

}

Okhttp 调用如下:


public void invoke(Request request, BaseAsyncResult result) {

        okHttpClient.newCall(request).enqueue(new Callback() {

            @Override

            public void onFailure(@NotNull Call call, @NotNull IOException e) {

                result.onFailure(e);

            }


            @Override

            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {

                result.onResponse(response);

            }

        });

    }

该应用程序使用 sdk 代码,如 iasClient 是 okhttp 客户端的包装器:


 BaseAsyncResult<AuthenticationResponse> iasAsyncResult = new BaseAsyncResult();

 iasClient.invoke(request, iasAsyncResult);

 AuthenticationResponse result = iasAsyncResult.getResult();

错误消息:


java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to x.x.x.AuthenticationResponse


我错过了什么?


三国纷争
浏览 153回答 2
2回答

慕仙森

您需要确保 jackson 知道将值反序列化到哪个类。在这种情况下,您要求 Jackson 将响应反序列化为 TypeReference ,默认情况下它将解析为 Map ,除非您指定类(在本例中为 AuthenticationResponse )。因此, Future 解析为 linkedHashMap 并导致类转换。尝试替换下面的行。future.complete(IasClientJsonUtil.json2Pojo(bodyString,&nbsp;new&nbsp;TypeReference<T>()&nbsp;{}));和future.complete(IasClientJsonUtil.json2Pojo(bodyString,&nbsp;new&nbsp;TypeReference<AuthenticationResponse>()&nbsp;{}));

收到一只叮咚

一种方法是将私有类类型变量添加到 BaseAsyncResult,然后在 json2Pojo 函数中使用该类,然后 BaseAsyncResult 可能如下所示:public class BaseAsyncResult<T> {&nbsp; &nbsp; private final CompletableFuture<T> future = new CompletableFuture<>();&nbsp; &nbsp; private Class<T> classType;&nbsp; &nbsp; public BaseAsyncResult(Class<T> classType) {&nbsp; &nbsp; &nbsp; &nbsp; this.classType = classType;&nbsp; &nbsp; }&nbsp; &nbsp; public T getResult() {&nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return future.get();&nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException | ExecutionException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }&nbsp; &nbsp; void onFailure(IOException e) {&nbsp; &nbsp; &nbsp; &nbsp; future.completeExceptionally(e);&nbsp; &nbsp; }&nbsp; &nbsp; void onResponse(Response response) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; future.complete(JacksonUtil.json2Pojo(response.body().string(), classType));&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Java
我要回答