规避改造" baseUrl必须以/"

时间:2017-11-16 14:06:54

标签: retrofit2

我使用 Retrofit 2.3.0 与OAI-PMH端点进行交互。

我现在碰巧与一个端点进行交互,这个端点对于它的基本URL是否以斜杠结尾是挑剔的:

没有斜线:

http://www.relacionesinternacionales.info/ojs/oai.html?verb=Identify按预期工作。

使用斜杠:

http://www.relacionesinternacionales.info/ojs/oai.html/?verb=Identify会导致重定向到404页面。

现在的问题是Retrofit 2.3.0要求基本URL以斜杠结尾。

为Retrofit构建器提供无结尾斜杠基础URL会让Retrofit抱怨。

为Retrofit构建器提供带有斜杠的结束URL会导致Retrofit构建错误的URL,从而导致404错误。

我如何规避这一限制?

1 个答案:

答案 0 :(得分:1)

作为一种解决方法,我使用 Java Reflection 来操纵Retrofit对象的baseUrl字段。

首先,代码检查提供的baseUrl是否以斜杠结尾。如果是这样,就不会发生任何特别的事情。

如果提供的baseUrl没有以斜杠结尾,则首先使用尾部斜杠创建retrofit对象baseUrl,然后将此baseUrl对象替换为原始对象非斜线结束的baseUrl:

String baseUrl = "..."; // can end with slash or not

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl( baseUrl.endsWith("/") ? baseUrl : baseUrl + "/" )
        .addConverterFactory(ScalarsConverterFactory.create())
        .build();

// workaround for https://stackoverflow.com/q/47331753/923560
if ( ! baseUrl.endsWith("/") ) {
    try {
        Field baseUrlField = retrofit.getClass().getDeclaredField("baseUrl");
        baseUrlField.setAccessible(true);
        HttpUrl newHttpUrl = HttpUrl.parse(baseUrl);
        baseUrlField.set(retrofit, newHttpUrl);
        baseUrlField.setAccessible(false);
    }
    catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
        LOG.error("Exception while manipulating baseUrl=" + baseUrl + " to not end with a slash", e);
        throw new RuntimeException(e);
    }
}

service = retrofit.create(OaiPmhService.class);
// ...