在Retrofit 2中传递API密钥 - Android Studio

时间:2017-02-27 17:11:14

标签: android api retrofit2

我正在开发一个Android APP,我正在使用Retrofit 2和The Movie Database API 3.我不确定如何正确传递API密钥,我试图使用@Header注释并试图将新的Interceptor添加到httpClient但仍然没有。

我尽可能多地研究,但没有任何帮助。 以下是我对API接口的了解:

public interface MoviesAPIService {
@GET("discover/movie?api_key={api_key}")
Call<List<MoviesResponse>> movieList(@Header("api_key") String api_key);}

以下是我在活动中的内容(它是ViewPager btw中的一个片段):

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.movies_fragment, container, false);

    movieListView = (ListView) rootView.findViewById(R.id.movieListView);

    final OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

    OkHttpClient client = httpClient.build();

    final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();


    MoviesAPIService moviesAPIService = retrofit.create(MoviesAPIService.class);
    Call<List<MoviesResponse>> call = moviesAPIService.movieList(apiKey);
    call.enqueue(new Callback<List<MoviesResponse>>() {
        @Override
        public void onResponse(Call<List<MoviesResponse>> call, retrofit2.Response<List<MoviesResponse>> response) {
            Log.d(TAG, "onResponse: " + response.body());
        }

        @Override
        public void onFailure(Call<List<MoviesResponse>> call, Throwable t) {

        }
    });
    return rootView;
}

我有很多不同的错误,具体取决于我正在测试的内容,并且使用此代码,我目前正在接收此错误:

URL query string "api_key={api_key}" must not have replace block. For dynamic query parameters use @Query.

对于API来说,我是一个初学者,所以也许我错过了一些东西。 谢谢你的帮助!

4 个答案:

答案 0 :(得分:2)

以上所有方法都是正确的,但是如果查询参数是api键,那么您必须在每个端点中手动添加声音是不好的...我们可以一次性完成此操作,而无需在其中添加api键您的查询参数每次。 您可以通过向OkHttpClient添加新的请求拦截器来实现。拦截实际请求并获取HttpUrl。添加查询参数需要使用http url,因为它将通过附加查询参数名称及其值来更改以前生成的请求url。

override fun getOkHttpClientBuilder(): OkHttpClient.Builder {
        val okHttpBuilder = super.getOkHttpClientBuilder()
        okHttpBuilder.addInterceptor { chain ->
            val request = chain.request().newBuilder()
                val originalHttpUrl = chain.request().url
                val url = originalHttpUrl.newBuilder().addQueryParameter("api_key", "your api key value").build()
                request.url(url)
            val response = chain.proceed(request.build())
            return@addInterceptor response
        }
        return okHttpBuilder
    }

答案 1 :(得分:1)

迟到的答案但我希望如果有人遇到这个问题会有帮助。

如果要将变量添加到api路径,则需要添加@Path表示法。在你的情况下将是:

@GET("discover/movie?api_key={api_key}")
Call<List<MoviesResponse>> movieList(@Path("api_key") String api_key);}

答案 2 :(得分:1)

您应该删除

  

?api_key = {api_key}

并从

更改
  

@Header to @Query

类似于以下代码

@GET ("discover/movie")

    Call<List<MoviesResponse>> movieList(@Query("api_key") String api_key);

这对我有用。

答案 3 :(得分:0)

扩展@VishalJha 答案:

fun create(): MyApiInterface {
    val client = OkHttpClient.Builder()
        .addInterceptor { chain -> return@addInterceptor addApiKeyToRequests(chain) }
        .build()
    return Retrofit.Builder()
        .baseUrl("your_url")
        .client(client)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
        .create(MyApiInterface::class.java)
}

private fun addApiKeyToRequests(chain: Interceptor.Chain): Response {
    val request = chain.request().newBuilder()
    val originalHttpUrl = chain.request().url
    val newUrl = originalHttpUrl.newBuilder()
        .addQueryParameter("api_key", "my_api_key").build()
    request.url(newUrl)
    return chain.proceed(request.build())
}