Android Java—将变量传递给接口

Android Java—将变量传递给接口,android,interface,retrofit,Android,Interface,Retrofit,我正在构建一个android应用程序,我正在使用改型从API检索数据。在这个应用程序中,我必须打3个电话。第一个很好用。第一个的代码如下。我有一节课 public class APIClient { private static Retrofit retrofit = null; static Retrofit getClient(){ HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); in

我正在构建一个android应用程序,我正在使用改型从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);
@标题({
“应用ID:3a97b932a9d449c981b595”,
“内容类型:应用程序/json”,
“appVersion:5.10.0”,
“apiVersion:3.0.0”
})
@POST(“/users/login”)
调用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()
        }
    })
call.enqueue(对象:回调{
覆盖fun onResponse(调用:调用,响应:响应){
if(response.code().toString().equals(“200”)){
val resource=response.body()
bearerToken=resource.session.bearerToken
if(bearerToken.isNotEmpty()&&bearerToken.isNotEmpty()){
val SharedReferences=GetSharedReferences(“设置”,Context.MODE\u PRIVATE)
val editor=SharedReferences.edit()
编辑器.putString(“bearerToken”,bearerToken)
editor.commit()
BearerToken.BearerToken=BearerToken
val i=意图(this@LoginActivity,UserAccountsActivity::class.java)
i、 putExtra(“Bealertoken”,Bealertoken)
星触觉(一)
}否则{
Toast.makeText(applicationContext,“请再试一次”),Toast.LENGTH\u LONG.show()
}
}否则{
println(“edwedw”+response.errorBody().string())
Toast.makeText(applicationContext,“不正确的电子邮件地址或密码。请检查并重试。”,Toast.LENGTH\u LONG.show()
}
}
覆盖失效时的乐趣(调用:调用,t:可丢弃){
call.cancel()
}
})
这个电话打得很好。 通过这个电话,我得到了一个代币。问题是我必须将此令牌作为头传递才能进行第二次调用。所以,第二个电话是这样的

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

@GET("/products")
Call<MainUserLogin> getUseraccounts ();
@标题({
“应用ID:3a97b932a9d449c981b595”,
“内容类型:应用程序/json”,
“appVersion:5.10.0”,
“apiVersion:3.0.0”,
“授权:”+***令牌***
})
@获取(“/产品”)
调用getUseraccounts();
有没有办法将变量从活动传递到接口以发出Api请求


非常感谢。

使用
改装
您可以使用多个
标题调用API,如下所示

@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);
@GET(“/products”)
调用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 ();
@标题({
“应用ID:3a97b932a9d449c981b595”,
“内容类型:应用程序/json”,
“appVersion:5.10.0”,
“apiVersion:3.0.0”,
“授权:”+***令牌***
})
@获取(“/产品”)
调用getUseraccounts();
这个。调用
getUseraccounts
方法时,可以解析从上一个
端点创建的令牌


试试这个,让我知道你的反馈。谢谢

使用
改型
可以使用多个
标题调用API,如下所示

@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);
@GET(“/products”)
调用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 ();
@标题({
“应用ID:3a97b932a9d449c981b595”,
“内容类型:应用程序/json”,
“appVersion:5.10.0”,
“apiVersion:3.0.0”,
“授权:”+***令牌***
})
@获取(“/产品”)
调用getUseraccounts();
这个。调用
getUseraccounts
方法时,可以解析从上一个
端点创建的令牌


试试这个,让我知道你的反馈。谢谢

收到令牌后,应将该令牌保存在中,因为认证令牌是应用程序进行进一步认证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);
    }
}

收到令牌后,应将该令牌保存在中,因为认证令牌是应用程序进行进一步认证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);
    }
}