如何在没有baseUrl的情况下设置Retrofit

时间:2016-01-17 19:04:24

标签: java android rest retrofit

我的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: 

如何解决?

7 个答案:

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

source

答案 2 :(得分:0)

如果您每次要进行api调用时都可以创建新的RestAdapter实例,则可以创建一个新的适配器,并将基本网址作为参数。

Using absolute URLs with Retrofit

答案 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),您必须使用默认方法并将结束路径作为参数传递。