Дооснащение - изменение 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
Два простых решения этой проблемы:
-
Жесткий код нового URL, оставляя базовый URL как есть:
@GET("http://example.com/api/")
Call<JSONObject> callMethodName();
-
Передайте новый 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();
}
и после того, как вам просто нужно использовать правильный.