使用Retrofit 2,您可以在服务方法的注释中设置完整的URL,如下所示:
public interface APIService {
@GET("http://api.mysite.com/user/list")
Call<Users> getUsers();
}
然而,在我的应用程序中,我的webservices的URL在编译时是不知道的,应用程序在下载的文件中检索它们,所以我想知道我如何使用Retrofit 2与完整的动态URL。
我试着设置一个完整的路径,像这样:
public interface APIService {
@GET("{fullUrl}")
Call<Users> getUsers(@Path("fullUrl") fullUrl);
}
new Retrofit.Builder()
.baseUrl("http://api.mysite.com/")
.build()
.create(APIService.class)
.getUsers("http://api.mysite.com/user/list"); // this url should be dynamic
.execute();
但是在这里,Retrofit并没有看到这个路径实际上是一个完整的URL,而是试图下载http://api.mysite.com/http%3A%2F%2Fapi.mysite.com%2Fuser%2Flist
任何提示,我可以使用这样的动态url改造?
谢谢你!
在Retrofit (MVVM)中使用Get和Post方法的动态URL
服务接口:
public interface NetworkAPIServices {
@POST()
Observable<JsonElement> executXYZServiceAPI(@Url String url,@Body AuthTokenRequestModel param);
@GET
Observable<JsonElement> executeInserInfo(@Url String url);
MVVM服务类:
public Observable<JsonElement> executXYZServiceAPI(ModelObject object) {
return networkAPIServices.authenticateAPI("url",
object);
}
public Observable<JsonElement> executeInserInfo(String ID) {
return networkAPIServices.getBank(DynamicAPIPath.mergeUrlPath("url"+ID)));
}
和改装客户端类
@Provides
@Singleton
@Inject
@Named("provideRetrofit2")
Retrofit provideRetrofit(@Named("provideRetrofit2") Gson gson, @Named("provideRetrofit2") OkHttpClient okHttpClient) {
builder = new Retrofit.Builder();
if (BaseApplication.getInstance().getApplicationMode() == ApplicationMode.DEVELOPMENT) {
builder.baseUrl(NetworkURLs.BASE_URL_UAT);
} else {
builder.baseUrl(NetworkURLs.BASE_URL_PRODUCTION);
}
builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
builder.client(okHttpClient);
builder.addConverterFactory(GsonConverterFactory.create(gson));
return builder.build();
}
例如
网址:https://gethelp.wildapricot.com/en/articles/549-changing-your
baseURL: https://gethelp.wildapricot.com
剩下的@Url: / zh /articles/549-changing-your(这是你在复古服务类中传递的信息)
步骤1
Please define a method in Api interface like:-
@FormUrlEncoded
@POST()
Call<RootLoginModel> getForgotPassword(
@Url String apiname,
@Field(ParameterConstants.email_id) String username
);
步骤2
对于最佳实践,定义一个用于改造实例的类:-
public class ApiRequest {
static Retrofit retrofit = null;
public static Retrofit getClient() {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.addInterceptor(logging)
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(URLConstants.base_url)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
步骤3
在活动中定义:-
final APIService request =ApiRequest.getClient().create(APIService.class);
Call<RootLoginModel> call = request.getForgotPassword("dynamic api
name",strEmailid);
从Retrofit 2.0.0-beta2开始,如果你有一个服务从这个URL响应JSON:
http://myhost/mypath
以下是无效的:
public interface ClientService {
@GET("")
Call<List<Client>> getClientList();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://myhost/mypath")
.addConverterFactory(GsonConverterFactory.create())
.build();
ClientService service = retrofit.create(ClientService.class);
Response<List<Client>> response = service.getClientList().execute();
但这是可以的:
public interface ClientService {
@GET
Call<List<Client>> getClientList(@Url String anEmptyString);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://myhost/mypath")
.addConverterFactory(GsonConverterFactory.create())
.build();
ClientService service = retrofit.create(ClientService.class);
Response<List<Client>> response = service.getClientList("").execute();
如果您已经设置了代码,并且不希望在可以更改的不同接口上进行更改,请使用此链接中描述的解决方案。
重点是更新URL并重新创建Retrofit构建器的changeApiBaseUrl方法。
public class ServiceGenerator {
public static String apiBaseUrl = "http://futurestud.io/api";
private static Retrofit retrofit;
private static Retrofit.Builder builder =
new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(apiBaseUrl);
private static OkHttpClient.Builder httpClient =
new OkHttpClient.Builder();
// No need to instantiate this class.
private ServiceGenerator() {
}
public static void changeApiBaseUrl(String newApiBaseUrl) {
apiBaseUrl = newApiBaseUrl;
builder = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(apiBaseUrl);
}
public static <S> S createService(Class<S> serviceClass, AccessToken token) {
String authToken = token.getTokenType().concat(token.getAccessToken());
return createService(serviceClass, authToken);
}
// more methods
// ...
}
你可以这样使用它:
public class DynamicBaseUrlActivity extends AppCompatActivity {
public static final String TAG = "CallInstances";
private Callback<ResponseBody> downloadCallback;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_upload);
downloadCallback = new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
Log.d(TAG, "server contacted at: " + call.request().url());
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.d(TAG, "call failed against the url: " + call.request().url());
}
};
// first request
FileDownloadService downloadService = ServiceGenerator.create(FileDownloadService.class);
Call<ResponseBody> originalCall = downloadService.downloadFileWithFixedUrl();
originalCall.enqueue(downloadCallback);
// change base url
ServiceGenerator.changeApiBaseUrl("http://development.futurestud.io/api");
// new request against new base url
FileDownloadService newDownloadService = ServiceGenerator.create(FileDownloadService.class);
Call<ResponseBody> newCall = newDownloadService.downloadFileWithFixedUrl();
newCall.enqueue(downloadCallback);
}
}