Ich habe ein Szenario, in dem ich eine API mit derselben Basis-URL aufrufen muss, z www.myAPI.com aber mit einem anderen baseUrl.
Ich habe eine Instanz von Retrofit 2, die über a erstellt wird Builder:
return new Retrofit.Builder()
.baseUrl(FlavourConstants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(okHttpClient)
.build();
Das FlavourConstants.BASE_URL sieht aus wie das:
public static final String BASE_URL = "http://myApi.development:5000/api/v1/";
Für einige WebRequestsmuss ich dieselbe API aufrufen, aber bei anderen muss ich sie von einer völlig anderen aufrufen BaseUrl. Wie ändere ich die Retrofit Instanz also zur Laufzeit auf eine andere URL zeigen?
Das Retrofit Instanz hat keine .setBaseUrl oder setter oder etwas ähnliches, da es über a gebaut wird Builder.
Irgendwelche Ideen?
wie du schon erwähnt hast, die Retrofit Die Instanz ist irgendwie unveränderlich (etwas, wofür Builder gedacht sind). Sie müssten also eine weitere Instanz für die andere URL erstellen, die Sie festlegen möchten.
– asg
6. August 2016 um 16:58 Uhr
stackoverflow.com/a/63076030/7511020 Wenn Sie dagger2 nicht verwenden, sehen Sie sich einfach nur Schritt 1 an und fügen Sie Ihren Interceptor zum HttpClient Builder-Objekt hinzu
– Zeeshan Akhtar
24. Juli 2020 um 14:55 Uhr
Nir Duan
Lucky for you Retrofit hat dafür eine einfache Lösung:
public interface UserManager {
@GET
public Call<ResponseBody> userName(@Url String url);
}
Das url String sollte die vollständige URL angeben, die Sie verwenden möchten.
Dies funktioniert nur für GET Methoden und nicht für HTTP Methoden wie z @POST. Ich habe das Problem gelöst und werde eine Antwort posten, sobald ich überprüft habe, ob es funktioniert.
– Subby
7. August 2016 um 17:10 Uhr
@Subby hast du überprüft, dass es funktioniert hat? Wo ist deine Antwort?
– Neon Warge
2. Oktober 2018 um 1:13 Uhr
Dies ist nicht die Lösung des ursprünglichen Problems, es ändert nicht die Basis-URL (und es verschmutzt auch die API). Es behält die ursprüngliche Basis-URL bei, ermöglicht es Ihnen jedoch, den Endpunkt für einen bestimmten Anruf vollständig zu ändern – es ist eine Problemumgehung, aber es löst nicht das vorliegende Problem. (und ja, ich habe es gerade ausprobiert, es funktioniert)
– Milosmen
3. Mai 2019 um 14:15 Uhr
@Subby warum diese Antwort nicht funktioniert mit @POST?
– Bitweise DEVS
20. März um 7:44 Uhr
Nachrüstung 2.4, MAI 2019
Zwei einfache Lösungen für dieses Problem sind:
Hardcodieren Sie die neue URL, während Sie die Basis-URL unverändert lassen:
NB: Diese Methoden funktionieren für GET oder POST. Diese Lösung ist jedoch nur effizient, wenn Sie nur eine Ausnahme von einer oder zwei anderen URLs als Ihrer Basis-URL verwenden müssen. Andernfalls können die Dinge in Bezug auf die Sauberkeit des Codes etwas chaotisch werden.
Wenn Ihr Projekt vollständig dynamisch generierte Basis-URLs erfordert, können Sie mit dem Lesen beginnen Dies.
Vlad
Auch gibt es einen solchen Hack in Kotlin beim Definieren der Basis-URL
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:443")
.toHttpUrlOrNull() ?: request.url
)
// OR
//.url(HttpUrl.parse(request.url().toString().replace("localhost", "yourdomain.com:443")) ?: request.url())
.build()
)
}
}
Phileo99
Die einfachste (aber nicht die leistungsstärkste) Möglichkeit, die Retrofit2-Basis-URL zur Laufzeit zu ändern, besteht darin, die Retrofit-Instanz mit der neuen URL neu zu erstellen:
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);
Wenn Sie OkHttp mit Retrofit verwenden, können Sie alternativ einen OkHttp-Interceptor wie hinzufügen Dieses hier Beim Erstellen Ihres OkHttp-Clients:
HostSelectionInterceptor hostInterceptor = new HostSelectionInterceptor();
hostInterceptor.setHost(newBaseUrl);
return new OkHttpClient.Builder()
.addInterceptor(hostInterceptor)
.build();
Vattic
Ich habe gerade die folgende Funktion verwendet, als ich auf dieses Problem gestoßen bin. aber ich hatte es eilig und ich glaube, ich muss einen anderen verwenden und ich habe “retrofit2:retrofit:2.0.2” verwendet
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;
}
[Update]
Ich habe das gefunden Verknüpfung Das erklärt die @Url, die als Parameter gesendet werden kann, und ich glaube, es ist professioneller als meine alte Lösung. Nachfolgend finden Sie das Szenario:
class HostSelectionInterceptor: Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
apiHost?.let { host ->
val request = chain.request()
val newUrl = request.url.newBuilder().host(host).build()
val newRequest = request.newBuilder().url(newUrl).build()
return chain.proceed(newRequest)
}
throw IOException("Unknown Server")
}
}
You just need to change at runtime the apiHost variable (var apiHost = "example.com"). Then add this interceptor to OkHttpClient builder:
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(HostSelectionInterceptor())
.build()
Catluc
Ok, wenn ich mich nicht falsch erinnere, sagt die Dokumentation von Retrofit, dass Sie auf eine andere URL verweisen können, wenn Sie einfach in Ihrem Schnittstellendienst die vollständige URL der ws hinzufügen, die sich von der BASE_URL in Retrofit Builder unterscheidet. Ein Beispiel…
public interface UserManager {
@GET("put here ur entire url of the service")
public Call<ResponseBody> getSomeStuff();
}
wie du schon erwähnt hast, die
Retrofit
Die Instanz ist irgendwie unveränderlich (etwas, wofür Builder gedacht sind). Sie müssten also eine weitere Instanz für die andere URL erstellen, die Sie festlegen möchten.– asg
6. August 2016 um 16:58 Uhr
stackoverflow.com/a/63076030/7511020 Wenn Sie dagger2 nicht verwenden, sehen Sie sich einfach nur Schritt 1 an und fügen Sie Ihren Interceptor zum HttpClient Builder-Objekt hinzu
– Zeeshan Akhtar
24. Juli 2020 um 14:55 Uhr