0

我正在使用 Retrofit 连接到用户可配置的 URL,我遇到的问题是如何处理空白 URL。正如预期的那样,当服务器为空/空白时,RestAdapter.Builder 会引发 IllegalArgumentException,这意味着无法调用 create 来生成改造接口,从而使我得到一个空接口。

例如使用以下 API 接口;

interface IApiService {
        @POST("/{path}/api/{userid}/calls/Action")
        void startCall(@Path("path") String path, @Path("userid") String userid, @Body Action action, Callback<Response> callback);

        @PUT("/{path}/api/{userid}/calls/Action")
        void addToCall(@Path("path") String path, @Path("userid") String userid, @Body Action action, Callback<Response> callback);
} 

我已经为 Retrofit 接口创建了一个包装类,因为回调类型是 Retrofit 回调,我希望能够在需要时将其换掉。

public class ApiServiceWrapper implements IAPiServiceWrapper {

        private IApiService mAPiService;

        @Inject
        ApiServiceWrapper(Settings settings, RequestInterceptor requestInterceptor) {

            RestAdapter restAdapter = new RestAdapter.Builder()
                    .setServer(settings.getUrl())
                    .setRequestInterceptor(requestInterceptor)
                    .setConverter(new ActionConverter())
                    .build();

            mAPiService = restAdapter.create(IApiService.class);
        }

        public void startCall(String path, String userid, Action action, final IApiResultCallback<Response> callback) {
            mAPiService.startCall(path, userid, action, new Callback<Response>() {
                @Override
                public void success(Response response, Response response2) {
                    callback.success();
                }

                @Override
                public void failure(RetrofitError error) {
                    callback.failure(error.getResponse().getReason());
                }
            });
        }

        public void addToCall(String path, String userid, Action action, final IApiResultCallback<Response> callback) {
            mAPiService.addToCall(path, userid, action, new Callback<Response>() {
                @Override
                public void success(Response response, Response response2) {
                    callback.success();
                }

                @Override
                public void failure(RetrofitError error) {
                    callback.failure(error.getResponse().getReason());
                }
            });
        }
    }

那么我应该如何处理 RestAdapter.Builder 抛出的异常呢?

在我看来,检查 settings.getUrl() 是否返回一个有效的 URL 似乎是明智的,如果确实如此,则使用 Retrofit 填充界面。但是当 URL 为空时如何处理这种情况,一种解决方案是检查 null,例如;

public void startCall(String path, String userid, Action action, final IApiResultCallback<Response> callback) {
    if (mAPiService != null) {
        mAPiService.startCall(path, userid, action, new Callback<Response>() {
            @Override
            public void success(Response response, Response response2) {
                callback.success();
            }

            @Override
            public void failure(RetrofitError error) {
                callback.failure(error.getResponse().getReason());
            }
        });
    } else {
           callback.failure("Some reason here :D");
    }
}

这可行,但我的 API 接口非常大,我宁愿不必在每次调用时检查 null。

例如,如果我可以将 mAPiService 设置为一个无效的实现,它会立即用一条消息调用失败,那就太好了;

@Inject
ApiServiceWrapper(Settings settings, RequestInterceptor requestInterceptor) {
        if (TextUtils.isEmpty(settings.getUrl())) {
            mAPiService = new InvalidSettingsApiService("some error")
        } else {
            RestAdapter restAdapter = new RestAdapter.Builder()
                    .setServer(settings.getUrl())
                    .setRequestInterceptor(requestInterceptor)
                    .setConverter(new ActionConverter())
                    .build();

            mAPiService = restAdapter.create(IApiService.class);
        }
}

但这是不可能的,因为 IApiService 接口使用 Retrofit Callback 接口,它需要一个失败参数 RetrofitError。

我列出的任何选项都可以吗?或者有没有更好的解决方案来处理无法生成界面的情况?

4

1 回答 1

1

我正在使用 Retrofit 连接到用户可配置的 URL ...

您应该立即验证并拒绝来自其来源的空白 URL。您的应用程序永远不应该RestAdapter使用无效的 URL 构建。

立即拒绝的一个重要原因是避免掩盖问题。如果存在不良数据,则需要在看到后立即显示出来,而不是将其隐藏在拒绝 API 调用的虚假接口实现之后。

于 2014-02-23T08:25:59.587 回答