Modify 2.0 interceptors

I am working with a modification and should be able to use multiple interceptors. I am currently using one to automatically add an authentication token, but I need to be able to make calls without an authentication token. If I add another interceptor that does not have an authentication token in the header, how do I use it instead of a token-token authenticator.

    val interceptor: Interceptor = Interceptor { chain ->
    val newRequest = chain.request().newBuilder().
            addHeader("Auth_Token", pref.getString(PSPreferences.prefAuthKey, "")).
            cacheControl(CacheControl.FORCE_NETWORK).
            build()
    chain.proceed(newRequest)
}

okHttpClient = OkHttpClient.Builder().
        readTimeout(1, TimeUnit.MINUTES).
        connectTimeout(1, TimeUnit.MINUTES).
        addInterceptor(interceptor).build()

val retrofitInstance = Retrofit.Builder()
        .baseUrl(APIEndpointInterface.BASE_URL)
        .client(okHttpClient)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
apiInterface = retrofitInstance.create<APIEndpointInterface>(APIEndpointInterface::class.java)

      

+3


source to share


1 answer


OkHttpClient

maintains a list of interceptors that you can access, however this is an unmodifiable collection.

This leaves us with three options, which I believe:

  • Create two OkHttpClient instances and subtract two instance modifications, one for unauthorized requests and one for authenticated requests.

  • Check if you should use an interceptor eg. in your authentication interceptor, you can first check if the key exists in your preference for the token, and if it uses it; If not, you just carry on without changing anything. You are doing this for your unauthenticated interceptor. I think this is the simplest solution for your case.

  • Create one interceptor that will maintain a mutable list of interceptors that you can add and remove as you see fit. You will need to keep a reference to this interceptor, perhaps make it a Singleton.

For the third option, I gave a very simple example:

public class HttpRequestResponseInterceptor implements Interceptor {

    public final List<RequestInterceptor> requestInterceptors = new ArrayList<>();
    public final List<ResponseInterceptor> responseInterceptors = new ArrayList<>();

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();

        for (RequestInterceptor interceptor : requestInterceptors) {
            request = interceptor.intercept(request);
        }

        Response response = chain.proceed(request);

        for (ResponseInterceptor interceptor : responseInterceptors) {
            response = interceptor.intercept(response);
        }

        return response;
    }

    public interface RequestInterceptor {
        Request intercept(Request request) throws IOException;
    }

    public interface ResponseInterceptor {
        Response intercept(Response response) throws IOException;
    }
}

      



In this case, you will need to implement user interfaces RequestInterceptor

and ResponseInterceptor

.

An example of what the implementation of these interfaces would look like:

public class ExampleInterceptor implements HttpRequestResponseInterceptor.RequestInterceptor,
 HttpRequestResponseInterceptor.ResponseInterceptor {

    @Override
    public Request intercept(Request request) throws IOException {
        return request.newBuilder().addHeader("REQUEST_HEADER", "EXAMPLE").build();
    }

    @Override
    public Response intercept(Response response) throws IOException {
        return response.newBuilder().addHeader("RESPONSE_HEADER", "EXAMPLE").build();
    }
}

      

Then you will need to add this interceptor to our main interceptor twice, once before requestInterceptors

and once before responseInterceptors

(or just one of them if it intercepts only requests or only responses).

This example is far from complete. The advantage of this solution is that it adds the ability to add and remove interceptors without having to re-instantiate OkHttpClient

. This requires additional work if you want to support retry requests, for example.

+2


source







All Articles