Stackoverflowerror Retrofit With Basic Authentication

Asked

Viewed 225 times

0

I have a Servicegenerator that creates the retrofit for min, it works great when I sign in and password for it, but when I try to use it without these options, my code goes into a loop and crash the app like this:

12-22 01:27:55.088 8500-8500/doupenglish.com.br.doup D/Error: ERR: stack=java.lang.StackOverflowError: stack size 8MB
at doupenglish.com.br.doup.Service.ServiceGenerator.createService(ServiceGenerator.java:29)
at doupenglish.com.br.doup.Service.ServiceGenerator.createService(ServiceGenerator.java:35)
at doupenglish.com.br.doup.Service.ServiceGenerator.createService(ServiceGenerator.java:35)
at doupenglish.com.br.doup.Service.ServiceGenerator.createService(ServiceGenerator.java:35) 
etc

My Servicegenerator class:

package doupenglish.com.br.doup.Service;

import android.text.TextUtils;

import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ServiceGenerator {

    private static final String API_BASE_URL = "http://api.doupenglish.com.br/";

    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    private static Retrofit retrofit = builder.build();

    public static <S> S createService(Class<S> serviceClass) {
        return createService(serviceClass, null, null);
    }

    public static <S> S createService(
            Class<S> serviceClass, String username, String password) {
        if (!TextUtils.isEmpty(username)
                && !TextUtils.isEmpty(password)) {
            String authToken = Credentials.basic(username, password);
            return createService(serviceClass, authToken);
        }

        return createService(serviceClass, null, null);
    }

    public static <S> S createService(
            Class<S> serviceClass, final String authToken) {
        if (!TextUtils.isEmpty(authToken)) {
            AuthenticationInterceptor interceptor =
                    new AuthenticationInterceptor(authToken);

            if (!httpClient.interceptors().contains(interceptor)) {
                httpClient.addInterceptor(interceptor);

                builder.client(httpClient.build());
                retrofit = builder.build();
            }
        }

        return retrofit.create(serviceClass);
    }
}

Interceptor

class AuthenticationInterceptor implements Interceptor {
    private String authToken;

    public AuthenticationInterceptor(String token) {
        this.authToken = token;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = chain.request();

        Request.Builder builder = original.newBuilder()
                .header("Authorization", authToken);

        Request request = builder.build();
        return chain.proceed(request);
    }
}

And the last call

    ApiInterface apidoup = ServiceGenerator.createService(ApiInterface.class);
    Call<List<NoticiaModel>> noticias = apidoup.getnoticias();
    noticias.enqueue(new Callback<List<NoticiaModel>>() {
        @Override
        public void onResponse(Call<List<NoticiaModel>> call, Response<List<NoticiaModel>> response) {
            if (response.isSuccessful()){
                //List<NoticiaModel> a = response.body();
                rv_noticas.setAdapter(new AdapterNoticias(getContext(),response.body()));
                mProgressDialog.dismiss();
            }else{
                Log.e(TAG, "onResponse: Erro API noticias " + response.code());
                mProgressDialog.dismiss();
            }
        }
        @Override
        public void onFailure(Call<List<NoticiaModel>> call, Throwable t) {
            Log.e(TAG, "onResponse: Erro API Conexao " + t);
            mProgressDialog.dismiss();

        }
    });

Solved:

    package doupenglish.com.br.doup.Service;

import android.text.TextUtils;

import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ServiceGenerator {

    private static final String API_BASE_URL = "http://api.doupenglish.com.br";

    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    private static Retrofit retrofit = builder.build();

    public static <S> S createService(Class<S> serviceClass) {
        return createService(serviceClass, null, null);
    }

    public static <S> S createService( Class<S> serviceClass, String username, String password) {
        if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)) {
            String authToken = Credentials.basic(username, password);
            if (!TextUtils.isEmpty(authToken)) {
                AuthenticationInterceptor interceptor =  new AuthenticationInterceptor(authToken);
                if (!httpClient.interceptors().contains(interceptor)) {
                    httpClient.addInterceptor(interceptor);
                    builder.client(httpClient.build());
                    retrofit = builder.build();
                }
            }
            return retrofit.create(serviceClass);
        }else{
            return retrofit.create(serviceClass);
        }
    }

}

1 answer

1


If the login password is not filled in, you invoke the same method createService(Class, String, String) again, infinitely. This causes the pile to burst. You need to rethink your logic at this point:

public static <S> S createService(Class<S> serviceClass, String username, String password) {
    ...
    return createService(serviceClass, null, null);
}
  • But this public Static <S> S createService(Class<S> serviceClass) { Return createService(serviceClass, null, null); } method does not require login and password. I don’t understand why he calls the other endlessly

  • I succeeded, I repeated my logic,

  • 1

    Here the staff of StackOverflow ;)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.