我的apiPath是完全动态的。我正在使用包含“ipAddress”和“SSLprotocol”等字段的项目。基于它们,我可以建立我的网址:
private String urlBuilder(Server server) {
String protocol;
String address = "";
if (AppTools.isDeviceOnWifi(activity)) {
address = serverToConnect.getExternalIp();
} else if (AppTools.isDeviceOnGSM(activity)) {
address = serverToConnect.getInternalIp();
}
if (server.isShouldUseSSL()) {
protocol = "https://";
} else {
protocol = "http://";
}
return protocol + address;
}
所以我的协议+地址可以是:http:// + 192.168.0.01:8010 = http://192.168.0.01:8010
我想这样使用它:
@FormUrlEncoded
@POST("{fullyGeneratedPath}/json/token.php")
Observable<AuthenticationResponse> authenticateUser(
@Path("fullyGeneratedPath") String fullyGeneratedPath,
@Field("login") String login,
@Field("psw") String password,
@Field("mobile") String mobile);
因此,authenticateUser的完整路径为http://192.168.0.01:8010/json/token.php - 例如。
这意味着我不需要任何basePath,因为我自己创建整个basePath,具体取决于我想要连接的服务器。
我的改造设置是:
@Provides
@Singleton
Retrofit provideRetrofit(OkHttpClient okHttpClient,
Converter.Factory converterFactory,
AppConfig appConfig) {
Retrofit.Builder builder = new Retrofit.Builder();
builder.client(okHttpClient)
.baseUrl(appConfig.getApiBasePath())
.addConverterFactory(converterFactory)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create());
return builder.build();
}
如果我删除baseUrl,则会收到此参数所需的错误。所以我将apiBasePath设置为:
public String getApiBasePath() {
return "";
}
然后我在创建改造实例后立即收到错误:
java.lang.IllegalArgumentException: Illegal URL:
如何解决?
答案 0 :(得分:32)
从source(新网址解析概念),您只需在帖子请求中指定整个路径。
此外,我们还可以在Retrofit 2.0中的@Post中声明一个完整的URL:
public interface APIService { @POST("http://api.nuuneoi.com/special/user/list") Call<Users> loadSpecialUsers(); }
此案例将忽略基本网址。
答案 1 :(得分:2)
只是这样使用
public interface UserService {
@GET
public Call<ResponseBody> profilePicture(@Url String url);
}
答案 2 :(得分:0)
如果您每次要进行api调用时都可以创建新的RestAdapter
实例,则可以创建一个新的适配器,并将基本网址作为参数。
答案 3 :(得分:0)
是的,你可以做到。我这样做了:
public APIHelper(BaseActivity activity) {
String url = Common.getAPIUrl();
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(url)
.build();
methods = restAdapter.create(IAppService.class);
}
基本上,一旦知道了端点网址,就需要创建改造对象。我想不再需要解释,因为代码是自我解释的。
假设只有基本网址被更改。
答案 4 :(得分:0)
我使用改造的方法
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.okhttp3:okhttp:3.10.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.10.0'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.1.8'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
这里我有一个通用类,里面有我的方法
public static AppServiceApi setMyRetrofit(){
Retrofit retrofit = null;
AppServiceApi appServices = null;
if (retrofit == null){
Gson gson = new GsonBuilder()
.setLenient()
.create(); //
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(getClient())
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
appServices = retrofit.create(AppServiceApi.class);
}
return appServices;
}
public static OkHttpClient getClient(){
HttpLoggingInterceptor interceptor=new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
/*.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)*/.build();
return client;
}
其中AppServiceApi接口包含我的所有结束网址和方法类型
答案 5 :(得分:0)
使用Retrofit 2,无论如何都必须放置基本URL。如果不知道,那么您通常可以输入任何URL,通常最好使用http://localhost/
。
答案 6 :(得分:0)
retrofit version :2.9.0 | gson version / okhttp : auto-set by retrofit
原始解决方案不适用于我,因为我的查询使用的是GET
。但这可能对您有用:
interface DownloaderApi {
@GET(".")
fun getData(): Call<List<TeacherDto>>
}
和
class TeacherDataDownloader {
private val downloaderApi: DownloaderApi
init {
val convertor = Gson()
val convertorFactory = GsonConverterFactory.create(convertor)
val retrofit =
Retrofit.Builder().baseUrl(FULL_URL).addConverterFactory(convertorFactory).build()
downloaderApi = retrofit.create(DownloaderApi::class.java)
}
fun getListOfTeachersSync(): List<TeacherDto>? = downloaderApi.getData().execute().body()
}
该解决方案部分地对我有用,因为我使用的某些链接以/
结尾(例如:const val FULL_URL = "https://jsonplaceholder.typicode.com/users/"
)。 但是,该解决方案仅适用于以/
结尾的API
对于不以/
结尾的URL(例如github gists),您必须使用默认方法并将结束路径作为参数传递。