jes*_*aul 5 java rest android retrofit2
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/
Run Code Online (Sandbox Code Playgroud)
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()));
}
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
@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) {
}
});
}
Run Code Online (Sandbox Code Playgroud)
小智 3
根据您的评论,我想说您正确地更改了构建器上的 API url,但您的第二次调用仍然使用 url 未更改的服务实例。
进一步解释一下,据我了解,这就是一切的执行方式:
dataProcessController.getApiClient()您的第一次调用中,您将获得指向第一个 url 的服务,然后执行调用。ServiceGenerator使用该新 url 更新。然后执行该logins()方法。dataProcessController.getApiClient()并用它进行第二次调用。但是,由于您从未 redid apiClient = ServiceGenerator.createService(ApiClient.class);,您获得的 apiClient 实例仍然指向第一个 url,因为它尚未收到 url 更改的通知。我在这里尝试的是将类getApiClient()中的方法更改DataProcessController为如下所示:
public ApiClient getApiClient() {
apiClient = ServiceGenerator.createService(ApiClient.class);
return apiClient;
}
Run Code Online (Sandbox Code Playgroud)
看看这样是否效果更好。
或者,如果您不想在该函数内重新生成服务,您也可以执行以下操作:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,每次更改 url 时,请执行以下操作:
ServiceGenerator.changeApiBaseUrl(baseUrls);
dataProcessController.regenerateClient();
Run Code Online (Sandbox Code Playgroud)
每次你这样做时,你应该得到一个指向正确网址的客户端dataProcessController.getApiClient()
| 归档时间: |
|
| 查看次数: |
5893 次 |
| 最近记录: |