1

i just learn about how can i implementing Retrofit with Dagger2 to set dynamic change url on this reference

i try to make simple module with HostSelectionInterceptor class to use that on Dagger2, but i can't make that correctly and i get error:

my NetworkModule:

@Module(includes = ContextModule.class)
public class NetworkModule {
    @Provides
    @AlachiqApplicationScope
    public HttpLoggingInterceptor loggingInterceptor() {
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Timber.e(message);
            }
        });
        interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
        return interceptor;
    }

    ...

    @Provides
    @AlachiqApplicationScope
    public HostSelectionInterceptor hostSelectionInterceptor() {
        return new HostSelectionInterceptor();
    }

    @Provides
    @AlachiqApplicationScope
    public OkHttpClient okHttpClient(HostSelectionInterceptor hostInterceptor, HttpLoggingInterceptor loggingInterceptor, Cache cache) {
        return new OkHttpClient.Builder()
                .addInterceptor(hostInterceptor)
                .addInterceptor(loggingInterceptor)
                .connectTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .cache(cache)
                .build();
    }
}

and HostSelectionInterceptor module:

@Module(includes = {NetworkModule.class})
public final class HostSelectionInterceptor implements Interceptor {
    private volatile String host;

    @Provides
    @AlachiqApplicationScope
    public String setHost(String host) {
        this.host = host;
        return this.host;
    }

    public String getHost() {
        return host;
    }

    @Provides
    @AlachiqApplicationScope
    @Override
    public okhttp3.Response intercept(Chain chain) {
        Request request = chain.request();
        String  host    = getHost();
        if (host != null) {
            HttpUrl newUrl = request.url().newBuilder()
                    .host(host)
                    .build();
            request = request.newBuilder()
                    .url(newUrl)
                    .build();
        }
        try {
            return chain.proceed(request);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

i get this error now:

java.lang.IllegalArgumentException: unexpected host: http://myUrl.com/ at okhttp3.HttpUrl$Builder.host(HttpUrl.java:754)

problem is set host by setHost method on this line of code:

HttpUrl newUrl = request.url().newBuilder()
        .host(host)
        .build();
DolDurma
  • 15,753
  • 51
  • 198
  • 377

2 Answers2

1

Based on this github comment, the solution is to replace

        HttpUrl newUrl = request.url().newBuilder()
                .host(host)
                .build();

with

        HttpUrl newUrl = HttpUrl.parse(host);
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • thanks, this problem solved, but i have another problem on get request, after change host by `intercepter` retrofit try to get request by older url which i set that to retrofit, please see this screen shot http://rupload.ir/upload/lknupff8l09lygr4gnso.png , code: `if (host != null) { HttpUrl newUrl = HttpUrl.parse(host); request = request.newBuilder() .url(newUrl) .build(); }` – DolDurma Aug 05 '17 at 09:15
0

You should use interceptor like this:

class HostSelectionInterceptor: Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        apiHost?.let { host ->
            val request = chain.request()
            val newUrl = request.url.newBuilder().host(host).build()
            val newRequest = request.newBuilder().url(newUrl).build()
            return chain.proceed(newRequest)
        }
        throw IOException("Unknown Server")
    }
}

You just need to change at runtime the apiHost variable (var apiHost = "example.com"). Then add this interceptor to OkHttpClient builder:

val okHttpClient = OkHttpClient.Builder()
    .addInterceptor(HostSelectionInterceptor())
    .build()