Java — передача переменной в интерфейс

Я создаю приложение для 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);

Код действия таков

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 ();

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

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

0
0
58
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Используя 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.

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

Как только вы получите токен, вы должны сохранить его в глобальный репозиторий, так как токен аутентификации понадобится вашему приложению для дальнейших аутентифицированных вызовов 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);
    }
}

Другие вопросы по теме