详解Retrofit2.0 公共参数(固定参数)

详解Retrofit2.0 公共参数(固定参数),第1张

概述本文主要介绍了Retrofit2.0公共参数固定参数),分享给大家,具体如下:请先阅读:

本文主要介绍了Retrofit2.0 公共参数(固定参数),分享给大家,具体如下:

请先阅读:
Retrofit 动态参数(非固定参数、非必须参数)(Get、Post请求)

在实际项目中,对于有需要统一进行公共参数添加的网络请求,可以使用下面的代码来实现:

RestAdapter restAdapter = new RestAdapter.Builder()    .setEndpoint(ctx).setRequestInterceptor(new RequestInterceptor() {     @OverrIDe     public voID intercept(RequestFacade request) {      request.addqueryParam("publicParams","1");     }    }).setConverter(new BaseConverter())    .build();

在RestAdapter的实例化对象的时候,为其指定一个RequestInterceptor接口的实现类即可,在该类中,可以对请求体的相关参数进行设置,如addheader、addqueryParam等。

不过遗憾的是Retrofit2.0已经没有了该类,该怎么做呢?通过Interceptor实现。

Interceptor是拦截器,在发送之前,添加一些参数,或者获取一些信息。

/** * 封装公共参数(Key和密码) * <p> */public class CommonInterceptor implements Interceptor { private final String mAPIKey; private final String mAPISecret; public CommonInterceptor(String APIKey,String APISecret) {  mAPIKey = APIKey;  mAPISecret = APISecret; } @OverrIDe public Response intercept(Interceptor.Chain chain) throws IOException {  String marvelHash = APIUtils.generateMarvelHash(mAPIKey,mAPISecret);  Request oldRequest = chain.request();  // 添加新的参数  httpUrl.Builder authorizedUrlBuilder = oldRequest.url()    .newBuilder()    .scheme(oldRequest.url().scheme())    .host(oldRequest.url().host())    .addqueryParameter(MarvelService.ParaM_API_KEY,mAPIKey)    .addqueryParameter(MarvelService.ParaM_TIMESTAMP,APIUtils.getUnixTimeStamp())    .addqueryParameter(MarvelService.ParaM_HASH,marvelHash);  // 新的请求  Request newRequest = oldRequest.newBuilder()    .method(oldRequest.method(),oldRequest.body())    .url(authorizedUrlBuilder.build())    .build();  return chain.proceed(newRequest); }}

Okhttp3使用了装饰者模式,使用Builder添加Interceptor。

CommonInterceptor commonInterceptor = new CommonInterceptor(    "key","Secret");OkhttpClIEnt clIEnt = new OkhttpClIEnt.Builder()    .addInterceptor(commonInterceptor)    .build();// 适配器Retrofit retrofit = new Retrofit.Builder()  .baseUrl("url")      .addConverterFactory(GsonConverterFactory.create()  .addCallAdapterFactory(RxJavaCallAdapterFactory.create())  .clIEnt(clIEnt)  .build();

有时候你找到了一条线,就能顺着线找到更多。

背景

在 AndroID http API 请求开发中经常遇到这样的需求:每一次请求带上一个或者多个固定不变的参数,例如:

设备唯一标识:device_ID = 7a4391e28f309c21 业务唯一标识:uID = 2231001 平台类型:platform = androID 客户端版本号:version_code = 6 …

这些参数是每一次发生请求都需要的,我们姑且称他们为公共参数(或者基础参数)。公共参数一般以 header line、url query 或者 post body(较少) 这些形式插入请求。

实现

如果使用 Okhttp 作为 http request clIEnt,这件事情就变得简单多了。Okhttp 提供了强大的拦截器组件 (Interceptor):

Interceptors are a powerful mechanism that can monitor,rewrite,and retry calls.

也就是说,Okhttp 的拦截器功能之一就是对将要发出的请求进行拦截、改造然后再发出。这正是我们想要的。BasicParamsInterceptor 实现了 okhttp3.Interceptor 接口。

实现 public Response intercept(Chain chain) throws IOException 方法。使用 Builder 模式,暴露以下接口:

addParam(String key,String value)

post 请求,且 body type 为 x-www-form-urlencoded 时,键值对公共参数插入到 body 参数中,其他情况插入到 url query 参数中。

addParamsMap(Map paramsMap)

同上,不过这里用键值对 Map 作为参数批量插入。

addheaderParam(String key,String value)

在 header 中插入键值对参数。

addheaderParamsMap(Map headerParamsMap)

在 header 中插入键值对 Map 集合,批量插入。

addheaderline(String headerline)

在 header 中插入 headerline 字符串,字符串需要符合 -1 != headerline.indexOf(“:”) 的规则,即可以解析成键值对。

addheaderlinesList(List headerlinesList)

同上,headerlineList: List 为参数,批量插入 headerline。

addqueryParam(String key,String value)

插入键值对参数到 url query 中。

addqueryParamsMap(Map queryParamsMap)

插入键值对参数 map 到 url query 中,批量插入。

示例

使用 BuIDer 模式创建 Interceptor 对象,然后调用 Okhttp 的 addInterceptor(Interceptor i) 方法将 interceptor 对象添加至 clIEnt 中:

BasicParamsInterceptor basicParamsInterceptor =  new OkPublicParamsInterceptor.Builder()    .addheaderParam("device_ID",DeviceUtils.getdeviceid())    .addParam("uID",usermodel.getInstance().getUID())    .addqueryParam("API_version","1.1")    .build();OkhttpClIEnt clIEnt = new OkhttpClIEnt.Builder()  .addInterceptor(basicParamsInterceptor)  .build();

Todo

自动时间戳公共参数的支持 动态参数的支持(例如登录后插入服务器返回的 uID)

源码

源码与引用:https://github.com/jkyeo/okhttp-basicparamsinterceptor

basicparamsinterceptor应用

配置基本提交参数

我们可以建一个拦截器,这里我举例加些简单的系统参数,如下:

 class httpBaseParamsLoggingInterceptor implements Interceptor{  @OverrIDe  public Response intercept(Chain chain) throws IOException {   Request request = chain.request();   Request.Builder requestBuilder = request.newBuilder();   Requestbody formBody = new FormBody.Builder()   .add("userID","10000")   .add("sessionToken","E34343RDfdrGRT43RFERGFRE")   .add("q_version","1.1")   .add("device_ID","androID-344365")   .add("device_os","androID")   .add("device_osversion","6.0")   .add("req_timestamp",System.currentTimeMillis() + "")   .add("app_name","forums")   .add("sign","md5")   .build();   String postbodyString = Utils.bodyToString(request.body());   postbodyString += ((postbodyString.length() > 0) ? "&" : "") + Utils.bodyToString(formBody);   request = requestBuilder     .post(Requestbody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"),postbodyString))     .build();   return chain.proceed(request);  } }

上面Utils类是使用的okio.Buffer里面的工具类。通过Requestbody构建要上传的一些基本公共的参数,然后通过”&”符号在http 的body里面其他要提交参数拼接。然后再通过requestBuilder重新创建request对象,然后再通过chain.proceed(request)返回Response 。

接下来在创建OkhttpClIEnt对象的时候修改为如下代码:

mOkhttpClIEnt = new OkhttpClIEnt.Builder()  .addInterceptor(interceptor)  .addInterceptor(new httpBaseParamsLoggingInterceptor())  .build();

这样就添加好了一些基本的公共参数。

下面我们借助BasicParamsInterceptor实现,代码如下:

public class BasicParamsInterceptor implements Interceptor { Map<String,String> queryParamsMap = new HashMap<>(); Map<String,String> paramsMap = new HashMap<>(); Map<String,String> headerParamsMap = new HashMap<>(); List<String> headerlinesList = new ArrayList<>(); private BasicParamsInterceptor() { } @OverrIDe public Response intercept(Chain chain) throws IOException {  Request request = chain.request();  Request.Builder requestBuilder = request.newBuilder();  // process header params inject  headers.Builder headerBuilder = request.headers().newBuilder();  if (headerParamsMap.size() > 0) {   Iterator iterator = headerParamsMap.entrySet().iterator();   while (iterator.hasNext()) {    Map.Entry entry = (Map.Entry) iterator.next();    headerBuilder.add((String) entry.getKey(),(String) entry.getValue());   }  }  if (headerlinesList.size() > 0) {   for (String line: headerlinesList) {    headerBuilder.add(line);   }  }  requestBuilder.headers(headerBuilder.build());  // process header params end  // process queryParams inject whatever it's GET or POST  if (queryParamsMap.size() > 0) {   injectParamsIntoUrl(request,requestBuilder,queryParamsMap);  }  // process header params end  // process post body inject  if (request.method().equals("POST") && request.body().ContentType().subtype().equals("x-www-form-urlencoded")) {   FormBody.Builder formBodyBuilder = new FormBody.Builder();   if (paramsMap.size() > 0) {    Iterator iterator = paramsMap.entrySet().iterator();    while (iterator.hasNext()) {     Map.Entry entry = (Map.Entry) iterator.next();     formBodyBuilder.add((String) entry.getKey(),(String) entry.getValue());    }   }   Requestbody formBody = formBodyBuilder.build();   String postbodyString = bodyToString(request.body());   postbodyString += ((postbodyString.length() > 0) ? "&" : "") + bodyToString(formBody);   requestBuilder.post(Requestbody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"),postbodyString));  } else { // can't inject into body,then inject into url   injectParamsIntoUrl(request,paramsMap);  }  request = requestBuilder.build();  return chain.proceed(request); } // func to inject params into url private voID injectParamsIntoUrl(Request request,Request.Builder requestBuilder,Map<String,String> paramsMap) {  httpUrl.Builder httpUrlBuilder = request.url().newBuilder();  if (paramsMap.size() > 0) {   Iterator iterator = paramsMap.entrySet().iterator();   while (iterator.hasNext()) {    Map.Entry entry = (Map.Entry) iterator.next();    httpUrlBuilder.addqueryParameter((String) entry.getKey(),(String) entry.getValue());   }  }  requestBuilder.url(httpUrlBuilder.build()); } private static String bodyToString(final Requestbody request){  try {   final Requestbody copy = request;   final Buffer buffer = new Buffer();   if(copy != null)    copy.writeto(buffer);   else    return "";   return buffer.readUtf8();  }  catch (final IOException e) {   return "dID not work";  } } public static class Builder {  BasicParamsInterceptor interceptor;  public Builder() {   interceptor = new BasicParamsInterceptor();  }  public Builder addParam(String key,String value) {   interceptor.paramsMap.put(key,value);   return this;  }  public Builder addParamsMap(Map<String,String> paramsMap) {   interceptor.paramsMap.putAll(paramsMap);   return this;  }  public Builder addheaderParam(String key,String value) {   interceptor.headerParamsMap.put(key,value);   return this;  }  public Builder addheaderParamsMap(Map<String,String> headerParamsMap) {   interceptor.headerParamsMap.putAll(headerParamsMap);   return this;  }  public Builder addheaderline(String headerline) {   int index = headerline.indexOf(":");   if (index == -1) {    throw new IllegalArgumentException("Unexpected header: " + headerline);   }   interceptor.headerlinesList.add(headerline);   return this;  }  public Builder addheaderlinesList(List<String> headerlinesList) {   for (String headerline: headerlinesList) {    int index = headerline.indexOf(":");    if (index == -1) {     throw new IllegalArgumentException("Unexpected header: " + headerline);    }    interceptor.headerlinesList.add(headerline);   }   return this;  }  public Builder addqueryParam(String key,String value) {   interceptor.queryParamsMap.put(key,value);   return this;  }  public Builder addqueryParamsMap(Map<String,String> queryParamsMap) {   interceptor.queryParamsMap.putAll(queryParamsMap);   return this;  }  public BasicParamsInterceptor build() {   return interceptor;  } }}

只要像上面一样配置就行了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

您可能感兴趣的文章:详解Retrofit 动态参数(非固定参数、非必须参数)(Get、Post请求)为Retrofit统一添加post请求的默认参数的方法Retrofit2.0 实现图文(参数+图片)上传方法总结 总结

以上是内存溢出为你收集整理的详解Retrofit2.0 公共参数(固定参数)全部内容,希望文章能够帮你解决详解Retrofit2.0 公共参数(固定参数)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1142891.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存