更新2 -动态URL

使用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改造?

谢谢你!

191761 次浏览

我认为你用错了。下面是更新日志的摘录:

新:@Url参数注释允许为端点传递一个完整的URL。

所以你的界面应该是这样的:

public interface APIService {
@GET
Call<Users> getUsers(@Url String url);
}
在Retrofit 2.0.0-beta2中,如果你有一个服务从这个URL响应JSON: http://myhost/mypath < / p >

以下是无效的:

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();

你可以在@Path注释上使用编码标志:

public interface APIService {
@GET("{fullUrl}")
Call<Users> getUsers(@Path(value = "fullUrl", encoded = true) String fullUrl);
}
  • 这将防止用%2F替换/
  • 然而,它不会让你避免?%3F取代,所以你仍然不能传入动态查询字符串。

我只想替换url的一部分,有了这个解决方案,我不需要传递整个url,只是动态部分:

public interface APIService {


@GET("users/{user_id}/playlists")
Call<List<Playlist> getUserPlaylists(@Path(value = "user_id", encoded = true) String userId);
}

步骤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;
}
< p >} 步骤3 在你的活动中定义:-

  final APIService request =ApiRequest.getClient().create(APIService.class);
Call<RootLoginModel> call = request.getForgotPassword("dynamic api
name",strEmailid);

你可以用这个:

@GET("group/{id}/users")

Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);

有关更多信息,请参阅文档https://square.github.io/retrofit/

如果你已经有了你的代码设置,你不想在不同的接口上做改变,使用链接中描述的解决方案。 主要的一点是changeApiBaseUrl方法,它更新URL并重新创建Retrofit构建器

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);
}
}

RetrofitHelper库是用kotlin编写的,可以让你使用几行代码进行API调用,并且你可以在每个调用中使用不同的url,头和参数

在你的应用类中添加多个url,如下所示:

class Application : Application() {


override fun onCreate() {
super.onCreate()


retrofitClient = RetrofitClient.instance
//api url
.setBaseUrl("https://reqres.in/")
//you can set multiple urls
//                .setUrl("example","http://ngrok.io/api/")
//set timeouts
.setConnectionTimeout(4)
.setReadingTimeout(15)
//enable cache
.enableCaching(this)
//add Headers
.addHeader("Content-Type", "application/json")
.addHeader("client", "android")
.addHeader("language", Locale.getDefault().language)
.addHeader("os", android.os.Build.VERSION.RELEASE)
}


companion object {
lateinit var retrofitClient: RetrofitClient


}
}

然后在调用中使用你需要的URL:

retrofitClient.Get<GetResponseModel>()
//set base url
.setBaseUrlKey("example")
//set path
.setPath("api/users/2")
//set url params Key-Value or HashMap
.setUrlParams("KEY","Value")
.setResponseHandler(GetResponseModel::class.java,
object : ResponseHandler<GetResponseModel>() {
override fun onSuccess(response: Response<GetResponseModel>) {
super.onSuccess(response)
//handle response
}
}).run(this)

有关更多信息,请参阅文档

在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();
}
例如< p > 这是url: https://gethelp.wildapricot.com/en/articles/549-changing-your

baseURL: https://gethelp.wildapricot.com

剩下的@Url: / zh /articles/549-changing-your(这是你在复古服务类中传递的信息)