I need to change base url at run time. I have login button and when login button click time i am called my login api like below :
login api = http://192.168.0.61/api/authenticate
API_BASE_URL = http://192.168.0.61/api/
when i get success response from first api i get client server url for changing baseUrl.
CompanyUrlConfigEntity companyUrlConfigEntity = response.body(); like below :
String clientUrl = companyUrlConfigEntity. getBaseUrl();
clientUrl = http://192.168.0.238/api/
In this project mainly for client or company based.So they have their own server. Each company has using more than 20 api's. So i need to change base url .
I am also checked below link for changing base url:
https://futurestud.io/tutorials/retrofit-2-how-to-change-api-base-url-at-runtime-2
and changed code like that
public static void changeApiBaseUrl(String newApiBaseUrl) {
API_BASE_URL = newApiBaseUrl;
builder = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(new NullOnEmptyConverterFactory())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new Gson()));
}
when i debugged and checked my baseUrl then it shows properly like below:
API_BASE_URL = http://192.168.0.238/api/
But when i call my customer api it shows the my first base url calling,
the url not changed.
expected customer api : http://192.168.0.238/api/customers
reality customer api : http://192.168.0.61/api/customers
I am also checked below link :
https://futurestud.io/tutorials/retrofit-2-how-to-use-dynamic-urls-for-requests
thats working , But each api need to pass fullPath url with each api like below:
@GET
public Call<ResponseBody> profilePicture(@Url String url);
But using this method , each api calling place i need to attach full path of url.
There is any other options? Please help me.
ServiceGenerator.class
public class ServiceGenerator {
public static String API_BASE_URL = "http://192.168.0.61/api/";
private static Retrofit retrofit;
private static OkHttpClient.Builder httpClient = new
OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(new NullOnEmptyConverterFactory())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new
Gson()));
private ServiceGenerator() {
}
public static void changeApiBaseUrl(String newApiBaseUrl) {
API_BASE_URL = newApiBaseUrl;
builder = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(new NullOnEmptyConverterFactory())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new Gson()));
}
public static Retrofit retrofit() {
return retrofit;
}
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null, null);
}
public static <S> S createService(Class<S> serviceClass,
final String authToken,
final ProgressListener progressListener) {
if (authToken != null) {
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
final String headerValue = AUTHORIZATION_TYPE + authToken;
Request request = original.newBuilder()
.header(AUTHORIZATION_HEADER_KEY, headerValue)
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
});
}
addResponseProgressListener(progressListener);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor httpLoggingInterceptor = new
HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(httpLoggingInterceptor);
}
if (authToken != null) {
if (picasso == null) {
setUpPicasso(authToken);
}
}
OkHttpClient client = httpClient.build();
httpClient.connectTimeout(15, TimeUnit.SECONDS);
httpClient.readTimeout(2, TimeUnit.MINUTES);
httpClient.writeTimeout(2, TimeUnit.MINUTES);
retrofit = builder.client(client).build();
return retrofit.create(serviceClass);
}
}
@OnClick(R.id.bt_login)
void onLogin() {
checkValidityOfUser();
}
private void checkValidityOfUser() {
final Login login = getLoginCredentials();
Call<CompanyUrlConfigEntity> callCheckValidity = dataProcessController.
getApiClient().
checkValidityOfUsers(login.getUsername());
callCheckValidity.enqueue(new Callback<CompanyUrlConfigEntity>() {
@Override
public void onResponse(Call<CompanyUrlConfigEntity> call,
Response<CompanyUrlConfigEntity> response) {
if (response.code() == 200) {
CompanyUrlConfigEntity companyUrlConfigEntity = response.body();
boolean status = companyUrlConfigEntity.isValidUser();
if (status) {
String baseUrls = companyUrlConfigEntity.
getBaseUrl();
baseUrls = baseUrls + "/api/";
ServiceGenerator.changeApiBaseUrl(baseUrls);
logins();
} else {
ToastHelper.show("please contact admin");
}
} else {
ToastHelper.show("" + response.code() + response.message());
}
}
@Override
public void onFailure(Call<CompanyUrlConfigEntity> call, Throwable t) {
ToastHelper.show("please contact admin");
}
});
}
private void logins() {
login = getLoginCredentials();
Call<Void> callLogin = dataProcessController.
getApiClient().
login(login);
callLogin.enqueue(new Callback<Void>() {
@Override
public void onResponse(Call<Void> call, Response<Void> response) {
if (response.code() == 200) {
} else if (response.code() == 401) {
}
}
@Override
public void onFailure(Call<Void> call, Throwable t) {
}
});
}
Base on your comments, I would say that you are correctly changing the API url on your builder, but that your second call still uses an instance of service where the url has not changed.
To explain a little more, from what I understand this is how everything gets executed:
dataProcessController.getApiClient()
in your first call, you are getting the service that is pointing to the first url and then execute the call.ServiceGenerator
with that new url. Then you execute the logins()
method.dataProcessController.getApiClient()
and do the second call with it. However, as you never redid apiClient = ServiceGenerator.createService(ApiClient.class);
, the apiClient instance you are getting is still pointing to the first url, because it hasn't been notified that the url changed.What I would try here, would be to change the method getApiClient()
in your DataProcessController
class to something like this:
public ApiClient getApiClient() {
apiClient = ServiceGenerator.createService(ApiClient.class);
return apiClient;
}
and see if this is work better.
Or if you don't want to regenerate the service inside that function, you can also do something like this:
public class DataProcessController {
private ApiClient apiClient = null;
private DataProcessController() {
regenerateClient();
}
public ApiClient getApiClient() { return apiClient; }
// add this to regenerate the client whenever url changes
public void regenerateClient() {
apiClient = ServiceGenerator.createService(ApiClient.class);
}
}
then, everytime you do change the url, do this:
ServiceGenerator.changeApiBaseUrl(baseUrls);
dataProcessController.regenerateClient();
and you should get a client that points to the correct url everytime you do dataProcessController.getApiClient()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With