【问题标题】:How to add interceptor to all API requests except one or two?如何将拦截器添加到除一个或两个之外的所有 API 请求?
【发布时间】:2017-09-12 22:45:17
【问题描述】:

我知道可以通过OkHttpClient 向所有请求添加拦截器,但我想知道是否可以向Okhttp 中的所有请求添加标头,但使用OkHttpClient 的一两个请求除外.

例如,在我的 API 中,所有请求都需要不记名令牌(Authorization: Bearer token-here 标头),但 oauth/token(获取令牌)和 api/users(注册用户)除外路线。是否可以在一个步骤中使用OkHttpClient 为除排除的请求之外的所有请求添加拦截器,还是应该为每个请求单独添加标头?

【问题讨论】:

    标签: java android retrofit2 okhttp3 okhttp


    【解决方案1】:

    @Omar 的回答很好 :) 但我找到了一种更简洁的方法来使用自定义注释来实现。

    添加注释

    @Target(AnnotationTarget.FUNCTION)
    @Retention(AnnotationRetention.RUNTIME)
    private annotation class DECRYPTRESPONSE
    

    在这样的拦截器中检查注释是真还是假

    val method = chain.request().tag(Invocation::class.java)!!.method()
        if(method.isAnnotationPresent(DECRYPTRESPONSE::class.java)) {
           //when annotion is present
    } else..
    

    在改造界面中添加注释

    @DECRYPTRESPONSE
    @GET
    Call<ItemsModel> getListing(@Url String url);
    

    下面是我的拦截器的完整代码,别忘了在 Okhttpclient builder 中添加拦截器

    @Target(AnnotationTarget.FUNCTION)
    @Retention(AnnotationRetention.RUNTIME)
    private annotation class DECRYPTRESPONSE
    
        class DecryptInterceptor : Interceptor {
        
            override fun intercept(chain: Interceptor.Chain): Response = chain
                .run {
                    proceed(request())
                }
                .let { response ->
                    return@let if (response.isSuccessful) {
        
                        val body = response.body!!
                        val contentType = body.contentType()
                        val charset = contentType?.charset() ?: Charset.defaultCharset()
                        val buffer = body.source().apply { request(Long.MAX_VALUE) }.buffer()
                        val bodyContent = buffer.clone().readString(charset)
        
                        val method = chain.request().tag(Invocation::class.java)!!.method()
        
                        if(method.isAnnotationPresent(DECRYPTRESPONSE::class.java)) {
                            response.newBuilder()
                                .body(ResponseBody.create(contentType, bodyContent.let(::decryptBody)))
                                .build()
                        }
                        else{
                            response.newBuilder()
                                .body(ResponseBody.create(contentType, bodyContent))
                                .build()
                        }
        
                    } else response
                }
        
            private fun decryptBody(content: String): String {
                
                  return content //your decryption code
            }
        }
    

    【讨论】:

      【解决方案2】:

      我找到了答案!

      基本上我像往常一样需要一个拦截器,我需要检查那里的 URL 以了解是否应该添加授权标头。

      import java.io.IOException;
      
      import okhttp3.Interceptor;
      import okhttp3.Request;
      import okhttp3.Response;
      
      /**
       * Created by Omar on 4/17/2017.
       */
      
      public class NetInterceptor implements Interceptor {
          @Override
          public Response intercept(Chain chain) throws IOException {
              Request request = chain.request();
              if (request.url().encodedPath().equalsIgnoreCase("/oauth/token")
                      || (request.url().encodedPath().equalsIgnoreCase("/api/v1/users") && request.method().equalsIgnoreCase("post"))) {
                  return  chain.proceed(request);
              }
              Request newRequest = request.newBuilder()
                      .addHeader("Authorization", "Bearer token-here")
                      .build();
              Response response = chain.proceed(newRequest);
              return response;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-11-18
        • 2023-03-18
        • 1970-01-01
        • 1970-01-01
        • 2020-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-05
        相关资源
        最近更新 更多