Дооснащение - изменение BaseUrl

У меня есть сценарий, когда мне нужно вызвать API с тем же BaseUrl, например. www.myAPI.com, но с другим baseUrl.

У меня есть экземпляр Retrofit 2, который построен через Builder:

return new Retrofit.Builder().baseUrl(FlavourConstants.BASE_URL).addConverterFactory(GsonConverterFactory.create(gson)).client(okHttpClient).build();

FlavourConstants.BASE_URL выглядит следующим образом:

public static final String BASE_URL = "http://myApi.development:5000/api/v1/";

Для некоторых WebRequests я должен называть тот же API, но в других случаях я должен называть его совершенно другим baseUrl. Как изменить экземпляр Retrofit таким образом, чтобы указать на другой URL-адрес во время выполнения?

В экземпляре Retrofit нет .setBaseUrl или setter или что-либо подобное, как оно было построено с помощью Builder.

Любые идеи?

Ответ 1

К счастью для вас Модернизация имеет простое решение для этого:

public interface UserManager {  
    @GET
    public Call<ResponseBody> userName(@Url String url);
}

Строка url должна указывать полный URL, который вы хотите использовать.

Ответ 2

Я просто использовал функцию ниже, когда столкнулся с этой проблемой. но я спешил, и я считаю, что я должен использовать другой, и я использовал "retrofit2: retrofit: 2.0.2"

public static Retrofit getClient(String baseURL) {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseURL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        } else {
            if (!retrofit.baseUrl().equals(baseURL)) {
                retrofit = new Retrofit.Builder()
                        .baseUrl(baseURL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
            }
        }
        return retrofit;
    }

[ Обновление ] Я нашел эту ссылку, объясняющую @Url, которую можно отправить в качестве параметра, и я считаю, что она более профессиональна, чем мое старое решение. Пожалуйста, найдите ниже сценария:

    interface APIService{
         @POST
         Call<AuthenticationResponse> login(@Url String loginUrl,[other parameters])
    }

И ниже метод в классе, который предоставляет модифицированный объект

public static Retrofit getClient() {
    if (retrofit==null) {
        retrofit = new Retrofit.Builder()
                .baseUrl("http://baseurl.com") // example url
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    return retrofit;
}

Затем вы можете вызвать метод, как показано ниже:

    APIInterface apiInterface = ApiClient.getClient2().create(ApiInterface.class);
    apiInterface.login("http://tempURL.com").enqueue(......);

Ответ 3

Самый простой (но не самый эффективный) способ изменить базовый URL Retrofit2 во время выполнения - перестроить экземпляр модификации новым URL-адресом:

private Retrofit retrofitInstance = Retrofit.Builder().baseUrl(FlavourConstants.BASE_URL).addConverterFactory(GsonConverterFactory.create(gson)).client(okHttpClient).build();

public void setNewBaseUrl(String url) {
   retrofitInstance = new Retrofit.Builder()
      .baseUrl(url)
      .addConverterFactory(GsonConverterFactory.create(gson))
      .client(okHttpClient).build();
}

...
retrofitInstance.create(ApiService.class);

В качестве альтернативы, если вы используете OkHttp с помощью Retrofit, вы можете добавить перехватчик OkHttp, например этот при создании клиента OkHttp:

HostSelectionInterceptor hostInterceptor = new HostSelectionInterceptor();
hostInterceptor.setHost(newBaseUrl);
return new OkHttpClient.Builder()
    .addInterceptor(hostInterceptor)
    .build();

Ответ 4

Дооснащение 2.4, май 2019

Два простых решения этой проблемы:

  1. Жесткий код нового URL, оставляя базовый URL как есть:

    @GET("http://example.com/api/")
    Call<JSONObject> callMethodName();
    
  2. Передайте новый URL в качестве аргумента, оставив базовый URL как есть:

    @GET
    Call<JSONObject> callMethodName(@Url String url);
    

Примечание: эти методы работают для GET или POST. Однако это решение эффективно только в том случае, если вам нужно использовать исключение из одного или двух URL-адресов, отличных от базового. В противном случае все может стать немного беспорядочным с точки зрения аккуратности кода.

Если ваш проект требует полностью динамически сгенерированных базовых URL, тогда вы можете начать читать это.

Ответ 5

Хорошо, если я не ошибаюсь, документы Retrofit говорят, что вы можете указать на другой URL-адрес, если просто добавите в свой интерфейс servicse полный URL-адрес ws, который отличается от BASE_URL в Retrofit Builder. Один пример...

public interface UserManager {  
    @GET("put here ur entire url of the service")
    public Call<ResponseBody> getSomeStuff();
}

Ответ 6

Также есть такой взлом в Kotlin при определении базового URL

например,

@FormUrlEncoded
@Headers("Accept: application/json")
@POST
suspend fun login(
    baseUrl: String,
    @Field("login") login: String,
    @Field("password") password: String
    @Url url: String = "$baseUrl/auth"
): ResponseAuth

Это не работает. Броски:

java.lang.IllegalArgumentException: No Retrofit annotation found. (parameter #1)

Единственный способ, предложенный Джейком Уортоном https://github.com/square/retrofit/issues/2161#issuecomment-274204152

Retrofit.Builder()
    .baseUrl("https://localhost/")
    .create(ServerApi::class.java)
class DomainInterceptor : Interceptor {

    @Throws(Exception::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        return chain.proceed(
            request.newBuilder()
                .url(
                    request.url.toString()
                        .replace("localhost", "yourdomain.com:80")
                        .toHttpUrlOrNull() ?: request.url
                )
                .build()
        )
    }
}

Ответ 7

Решение состоит в том, чтобы иметь два отдельных экземпляра модификации, один для вашего базового URL FLAVORED, а другой для другого базового URL.

Итак, просто определите две функции:

     public Retrofit getFlavouredInstance() {
        return new Retrofit.Builder().baseUrl(FlavourConstants.BASE_URL).addConverterFactory(GsonConverterFactory.create(gson)).client(okHttpClient).build();
     }

     public Retrofit getOtherBaseUrl() {
        return Retrofit.Builder().baseUrl(OTHER_BASE_URL).addConverterFactory(GsonConverterFactory.create(gson)).client(okHttpClient).build();
     }

и после того, как вам просто нужно использовать правильный.