Retrofit2 的异常处理

Exception handling with Retrofit2

我正在学习如何使用Retrofit2,但我遇到了麻烦。

是否有任何方法可以在 retrofit2.Retrofit 上捕获 Response 对象并在 HTTP 响应代码超出 2xx 范围时抛出异常?

我正在实现一些 JAX-RS 休息服务,我的休息方法调用另一个休息 API 来收集信息,我想在 JAX-RS 端处理任何 HTTP 错误:

public class HelloRest {

    @GET("/ping")
    public String ping() throws IOException {
        HelloService client = HelloServiceBuilder.getInstance();
        String response = client.sayHello().execute().body();
        LOGGER.info(response);
    }

    @GET ("echo/{msg}")
    public String echo(@PathParam("msg") String msg) throws IOException {
        HelloService client = HelloServiceBuilder.getInstance();
        String response = client.echo(msg).execute().body();
        LOGGER.info(response);
        return response;
    }
}

首先,我意识到 execute() 方法会抛出 IOException,因此我不得不将其添加到其余方法签名中。没关系,我可以用 JAX-RS 妥善处理它。

但是处理与响应代码超出 2xx 范围的 HTTP 响应相关的错误的最佳方法是什么?

我不想像这样使用 Retrofit2 时随时编写重复的代码块来检查 HTTP 响应代码:

Response<String> response = client.ping().execute();
int responseCode = response.code();
if (responseCode < 200 && responseCode > 299) {
    throws AnyException("...");
}

String serverResponse = response.body();
...

我可以在 Retrofit.Builder() 代码块中添加一些内容以某种方式以一般方式处理这种情况吗?

public final class HelloServiceBuilder {

    private static final String SERVICE_URL = "...";

    private HelloServiceBuilder() {
        // do nothing
    }

    public static HelloService getInstance() {
        Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(SERVICE_URL)
            .addConverterFactory(ScalarsConverterFactory.create())
            .HOW-TO-CHECK-RESPONSES-HERE?
            .build();

        return retrofit.create(HelloService.class);
    }
}

我将使用 JAX-RS 创建我的休息客户端 class。它是 Java 的一部分,我不需要向我的 pom 添加额外的依赖项,就像一个魅力,我只需要创建一个 class 而不是 2 个或更多:

public final class MyRestClient {
    private static Client client = ClientBuilder.newClient();

    public static String hello() {
        String serviceUrl = "http://..../";
        String path ="hello";

        Response response = client
                .target(serviceUrl)
                .path(path)
                .request(ExtendedMediaType.APPLICATION_UTF8)
                .get();

        if (response.getStatus() == Response.Status.OK.getStatusCode()) {
            return response.getEntity(String.class);
        }

        throw new WebApplicationException(response);
    }
}