Java - Передача переменной в интерфейс - PullRequest
0 голосов
/ 08 апреля 2019

Я создаю приложение для Android и использую Retrofit для извлечения данных из API. В этом приложении я должен сделать 3 звонка. Первый работает нормально. Код для первого ниже. У меня один класс

public class APIClient {

private static Retrofit retrofit = null;

static Retrofit getClient(){

    HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
    interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();

    retrofit = new Retrofit.Builder()
            .baseUrl("https://api_app.com")
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();

    return retrofit;
}
}

Также у меня есть этот интерфейс

@Headers({
        "AppId: 3a97b932a9d449c981b595",
        "Content-Type: application/json",
        "appVersion: 5.10.0",
        "apiVersion: 3.0.0"
})

@POST("/users/login")
Call<MainUserLogin> logInUser(@Body LoginBody loginBody);

Код Actvity:

call.enqueue(object : Callback<MainUserLogin> {
        override fun onResponse(call: Call<MainUserLogin>, response: Response<MainUserLogin>) {

            if (response.code().toString().equals("200")){

                val resource = response.body()

                bearerToken = resource.session.bearerToken

                if (bearerToken.isNotEmpty() && bearerToken.isNotBlank()){
                    val sharedPreferences = getSharedPreferences("Settings", Context.MODE_PRIVATE)
                    val  editor = sharedPreferences.edit()
                    editor.putString("bearerToken", bearerToken)
                    editor.commit()

                    BearerToken.bearerToken = bearerToken
                    val i = Intent(this@LoginActivity, UserAccountsActivity::class.java)
                    i.putExtra("bearerToken", bearerToken)
                    startActivity(i)
                }else{
                    Toast.makeText(applicationContext, "Please try again.", Toast.LENGTH_LONG).show()
                }


            }else{

                println("edwedw   "+response.errorBody().string())

                Toast.makeText(applicationContext, "Incorrect email address or password. Please check and try again.", Toast.LENGTH_LONG).show()
            }

        }

        override fun onFailure(call: Call<MainUserLogin>, t: Throwable) {
            call.cancel()
        }
    })

Этот звонок работает нормально. С этим звонком я получаю один жетон. Проблема в том, что мне нужно передать этот токен в качестве заголовка, чтобы сделать второй вызов. Итак, второй звонок будет таким:

@Headers({
        "AppId: 3a97b932a9d449c981b595",
        "Content-Type: application/json",
        "appVersion: 5.10.0",
        "apiVersion: 3.0.0",
        "Authorization: "+***Token***
})

@GET("/products")
Call<MainUserLogin> getUseraccounts ();

Есть ли способ передать переменную из Activity в интерфейс для выполнения запроса Api?

Большое спасибо.

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

Получив токен, вы должны сохранить этот токен в глобальном хранилище , поскольку токен аутентификации - это то, что понадобится вашему приложению для выполнения дальнейших аутентифицированных вызовов API.

После этого определите AuthorizationHeaderInterceptor, который будет расширяться okhttp3.Interceptor.Переопределите метод intercept этого перехватчика, чтобы добавить токен аутентификации к вашему запросу.

@Override
public Response intercept(@NonNull Chain chain) {
    return completeRequest(chain);
}

private Response completeRequest(@NonNull Interceptor.Chain chain) {
    AuthToken authToken = authTokenRepository.get();
    Request.Builder requestBuilder = chain.request().newBuilder();
    if (authToken != null && chain.request().header(Authorization.NAME) == null) {
        requestBuilder.addHeader(Authorization.NAME, Authorization.getValue(authToken.getIdToken()));
    }
    Request request = requestBuilder.build();
    try {
        return chain.proceed(request);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

Перехватчик можно добавить при сборке okhttpClient.

okHttpClientBuilder.addInterceptor(new AuthorizationHeaderInterceptor(authTokenRepository))

Обратите внимание, что Authorization класс - это простой вспомогательный класс, который инкапсулирует имя заголовка авторизации и формат значения.

public class Authorization {
    public static final String NAME = "Authorization";

    @NonNull
    public static String getValue(@NonNull String accessToken) {
        return String.format("Bearer %s", accessToken);
    }
}
1 голос
/ 08 апреля 2019

Используя Retrofit, вы можете вызывать API с несколькими headers следующим образом

@GET("/products")
    Call<MainUserLogin> getUseraccounts(@Header("AppId") String appId, @Header("Content-Type") String contentType, @Header("appVersion") String appVersion, @Header("apiVersion") String apiVersion, @Header("Authorization") String token);

Вместо

@Headers({
        "AppId: 3a97b932a9d449c981b595",
        "Content-Type: application/json",
        "appVersion: 5.10.0",
        "apiVersion: 3.0.0",
        "Authorization: "+***Token***
})

@GET("/products")
Call<MainUserLogin> getUseraccounts ();

это. Когда вы вызываете метод getUseraccounts, вы можете проанализировать токен, который вы создали из предыдущего endpoint.

Попробуйте и дайте мне знать ваши отзывы. Спасибо!

...