android Retrofit+OKhttp实现接口调用
2017-10-16 17:36
671 查看
前言
最近几个项目都是使用的Retofit+OKHttp的来实现接口调用的,再之前的框架中本次加入了from表单的提交方式。为了方便自己以及大家整合了下,方便以后的工作开展一.数据返回Model类
package com.reach.doooly.http.base; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import com.reach.doooly.bean.RHBaseVo; import retrofit2.http.Multipart; import retrofit2.http.POST; /** * @author fqming * <p> * 公用的返回信息bean */ public class CommResultBeanVo extends RHBaseVo { //错误码 private String code; //信息 //下面的注释只有在gson中使用才有效 // @Expose // @SerializedName("msg") private String msg; //返回信息 public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } private String data; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getData() { return data; } public void setData(String data) { this.data = data; } /**純屬為了不該其他的方法而添加的方法*/ public String getMessage(){ return msg; } @Override public String toString() { return "CommResultBeanVo{" + "code='" + code + '\'' + ",' message='" + msg + '\'' + ", data='" + data + "'\'}"; } }
该类实为了方便数据解析,尤其是小编很不喜欢写json数据解析,喜欢用GSON,也是谷歌推荐的。
二.返回码
与后台服务端一起约定返回码,然后有下面的类下面是小编与后端约定的返回码
package com.reach.doooly.http.client; /** * Created by tang on 2017/8/3 0003. */ public class ClientCode { //成功 public static final int SUCCESS_CODE=1000; //token失效 public static final int OUTTOKEN_CODE=40001; }
三.Client Base类
package com.reach.doooly.http.client; import io.reactivex.Observable; import io.reactivex.ObservableSource; import io.reactivex.ObservableTransformer; import io.reactivex.Observer; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.functions.Function; import io.reactivex.schedulers.Schedulers; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import okhttp3.ConnectionPool; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.fastjson.FastJsonConverterFactory; import android.annotation.SuppressLint; import android.content.Context; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import com.reach.doooly.http.base.BaseApiService; import com.reach.doooly.http.base.CommResultBeanVo; import com.reach.doooly.http.converfactory.StringConverterFactory; import com.reach.doooly.http.cookie.CookieCacheImpl; import com.reach.doooly.http.cookie.CookieManager; import com.reach.doooly.http.cookie.SharedPrefsCookiePersistor; import com.reach.doooly.http.errorhandler.NetException; import com.reach.doooly.http.errorhandler.RxErrorHandlingCallAdapterFactory; import com.reach.doooly.http.interceptor.DefaultHeaderInterceptor; import com.reach.doooly.http.interceptor.OfflineCacheControlInterceptor; import com.reach.doooly.http.util.Util; import com.reach.doooly.utils.StringUtlis; import okhttp3.RequestBody; import okhttp3.ResponseBody; /** * @author qinming.fu@reach-core.com * <p> * {@link # https://github.com/NeglectedByBoss/RetrofitClient} */ public final class Client { public static final String TAG = "RetrofitClient"; private static Retrofit.Builder retrofitBuilder; private static OkHttpClient.Builder okhttpBuilder; @SuppressLint("StaticFieldLeak") private static Context mContext; private static BaseApiService apiService; public static void init(Context context) { mContext = context; } /** * methodHandler */ private static List<Type> methodHandler(Type[] types) { List<Type> needTypes = new ArrayList<>(); for (Type paramType : types) { // if Type is T if (paramType instanceof ParameterizedType) { Type[] parenTypes = ((ParameterizedType) paramType).getActualTypeArguments(); for (Type childType : parenTypes) { needTypes.add(childType); if (childType instanceof ParameterizedType) { Type[] childtypes = ((ParameterizedType) childType).getActualTypeArguments(); Collections.addAll(needTypes, childtypes); } } } } return needTypes; } private static <T> Type getFinalType(final Observer<T> observable) { final Type[] types = observable.getClass().getGenericInterfaces(); if (methodHandler(types) == null || methodHandler(types).size() == 0) { return null; } return methodHandler(types).get(0); } private final ObservableTransformer schedulersTransformer = new ObservableTransformer() { @Override public ObservableSource apply(Observable upstream) { return upstream.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()); } }; private <T> Function parseBaseResultFunction(final Type type) { return new Function() { @Override public T apply(Object o) throws Exception { ResponseBody body = (ResponseBody) o; byte[] bytes = body.bytes(); CommResultBeanVo result = null; try { //result=new Gson().fromJson(new String(bytes),CommResultBeanVo.class);[不可这样使用,gson要求后面数据类型必须一样一样的] result = JSON.parseObject(new String(bytes), new TypeReference<CommResultBeanVo>() { }); } catch (Exception e) { result = null; } if (result != null && !StringUtlis.isEmpty(result.getCode())) { int code=-1; try{ code=Integer.parseInt(result.getCode()); }catch (Exception e){ code=-1; } if (code==ClientCode.SUCCESS_CODE) { } else { String errMsg = result.getMessage(); if (StringUtlis.isEmpty(errMsg)) { errMsg = ""; } throw new NetException(code, errMsg); } } else { throw new NetException(-1, ""); } return (T) result; } }; } @SuppressWarnings("unchecked") private <T> void compose(Observable respBody, final Observer<T> observer, ObservableTransformer transformer) { if (transformer != null) { respBody.compose(schedulersTransformer).compose(transformer).subscribe(observer); } else { respBody.compose(schedulersTransformer).subscribe(observer); } } public <T> void get(final String path, final Map<String, Object> parameters, final Observer<T> observer) { Observable respBody = apiService.get(path, parameters).map(parseBaseResultFunction(getFinalType(observer))); compose(respBody, observer, null); } public <T> void postForm(final String path, final Map<String, Object> parameters, final Observer<T> observer) { Observable respBody = apiService.post(path, parameters).map(parseBaseResultFunction(getFinalType(observer))); compose(respBody, observer, null); } public <T> void postJson(final String path, final Map<String, Object> parameters, final Observer<T> observer) { RequestBody body = Util.createJsonBody(Util.jsonStringFromMap(parameters)); Observable respBody = apiService.postJson(path, body).map(parseBaseResultFunction(getFinalType(observer))); compose(respBody, observer, null); } public <T> void postJson(final String path, final Map<String, Object> parameters, final Observer<T> observer, Type type, final ObservableTransformer transformer) { RequestBody body = Util.createJsonBody(Util.jsonStringFromMap(parameters)); Observable respBody = apiService.postJson(path, body).map(parseBaseResultFunction(type)); compose(respBody, observer, transformer); } public static final class Builder { private static final int TIMEOUT_READ = 15; private static final int TIMEOUT_CONNECTION = 15; private static final int DEFAULT_MAXIDLE_CONNECTIONS = 5; private static final long DEFAULT_KEEP_ALIVEDURATION = 8; private static final long CACHE_MAX_SIZE = 10 * 1024 * 1024; private String baseUrl; public Builder() { // Add the base url first. This prevents overriding its behavior but also // ensures correct behavior when using novate that consume all types. okhttpBuilder = new OkHttpClient.Builder(); retrofitBuilder = new Retrofit.Builder(); } /** * Create the {@link Retrofit} instance using the configured values. * <p/> * Note: A default {@link OkHttpClient} will be created and used. */ public Client build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); } if (mContext == null) { throw new IllegalStateException("context required."); } if (okhttpBuilder == null) { throw new IllegalStateException("okhttpBuilder required."); } if (retrofitBuilder == null) { throw new IllegalStateException("retrofitBuilder required."); } /** * Set a fixed API base URL. * * @see #baseUrl(HttpUrl) */ Interceptor cacheInterceptor = new OfflineCacheControlInterceptor(); HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(); loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); okhttpBuilder.cookieJar(new CookieManager(new CookieCacheImpl(), new SharedPrefsCookiePersistor(mContext))) .addInterceptor(loggingInterceptor) //设置Cache目录 //.cache(new Cache(mContext.getCacheDir(), CACHE_MAX_SIZE)) //设置缓存 //.addInterceptor(cacheInterceptor) .addNetworkInterceptor(cacheInterceptor) //失败重连 .retryOnConnectionFailure(true) .connectionPool(new ConnectionPool(DEFAULT_MAXIDLE_CONNECTIONS, DEFAULT_KEEP_ALIVEDURATION, TimeUnit.SECONDS)) //time out .readTimeout(TIMEOUT_READ, TimeUnit.SECONDS) .connectTimeout(TIMEOUT_CONNECTION, TimeUnit.SECONDS); /** * create okHttpClient */ OkHttpClient okHttpClient = okhttpBuilder.build(); /** * set Retrofit client */ retrofitBuilder.client(okHttpClient) .baseUrl(baseUrl) //error 转换器 .addCallAdapterFactory(RxErrorHandlingCallAdapterFactory.create(mContext)) //Rx .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //String转换器 .addConverterFactory(StringConverterFactory.create()) //fastjson转化器 .addConverterFactory(FastJsonConverterFactory.create()); apiService = retrofitBuilder.build().create(BaseApiService.class); return new Client(); } /** * Set an API base URL which can change over time. */ public Builder baseUrl(String baseUrl) { this.baseUrl = Util.checkNotNull(baseUrl, "baseUrl == null"); return this; } /** * Add Header for serialization and deserialization of objects. */ public <T> Builder addHeader(Map<String, T> headers) { okhttpBuilder.addInterceptor(new DefaultHeaderInterceptor<>(Util.checkNotNull(headers, "header == null"))); return this; } /** * Returns a modifiable list of interceptors that observe a single network request and response. * These interceptors must call {@link Interceptor.Chain#proceed} exactly once: it is an error * for a network interceptor to short-circuit or repeat a network request. */ public Builder addInterceptor(Interceptor interceptor) { okhttpBuilder.addInterceptor(Util.checkNotNull(interceptor, "interceptor == null")); return this; } } }
四.自己的类的基本实现
package com.reach.doooly.server; import io.reactivex.Observer; import okhttp3.Callback; import okhttp3.ConnectionPool; import okhttp3.Interceptor; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; import com.reach.doooly.base.log.Logs; import com.reach.doooly.consts.Constans; import com.reach.doooly.http.base.CommResultBeanVo; import com.reach.doooly.http.client.Client; import com.reach.doooly.http.interceptor.OfflineCacheControlInterceptor; import com.reach.doooly.utils.StringUtlis; import com.reach.doooly.utils.UserManager; /** * @author qinming.fu@reach-core.com * <p> * <p> * 网络基础请求服务, 所有的接口都需要调用此接口 */ public final class NetService { public static final String TAG = "NetService"; private static final String HEADER_TOKEN_KEY = "Token"; private static final String HEADER_APPVERSION_KEY = "AppVersion"; private static final String HEADER_CHANNELID_KEY = "Channel"; private static final String HEADER_TIMESTAMP_KEY = "Time"; //public static String COMM_TOKEN=""; // RHConstants.DEBUG_URL public static String ufttt = Constans.SERVICE_URL; public static Client client = new Client.Builder().baseUrl(ufttt) .addHeader(defaultHeader()).build(); private static NetService INSTANCE; public static synchronized NetService getInstance() { if (INSTANCE == null) { INSTANCE = new NetService(); } return INSTANCE; } private NetService() { } public static Map<String, String> defaultHeader() { Map<String, String> map = new HashMap<>(); if (!StringUtlis.isEmpty(UserManager.getInstance().getToken())) { String cookie = "token=" + UserManager.getInstance().getToken(); if (!StringUtlis.isEmpty(UserManager.getInstance().getUserId())) { cookie += ";uid=" + UserManager.getInstance().getUserId(); } map.put("Cookie", cookie); } map.put(HEADER_CHANNELID_KEY, "10002"); return map; } /** * 版本更新接口 * * @param map * @param obj */ public void updateVersion(Map<String, Object> map, Observer<CommResultBeanVo> obj) { client.postJson("。。。", map, obj); } /** * 我要申诉提交信息 * @param params * @param files * @param callback */ public void commitAgainst(Map<String,Object> params,List<File> files, Callback callback){ sendMultipart("。。。",params,files,callback); } /** * 上传多张图片及参数 * * @param reqUrl URL地址 * @param params 参数 */ public void sendMultipart(String reqUrl, Map<String,Object> params, List<File> files, Callback callback) { MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder(); multipartBodyBuilder.setType(MultipartBody.FORM); //遍历map中所有参数到builder if (params != null) { for (String key : params.keySet()) { multipartBodyBuilder.addFormDataPart(key, params.get(key).toString()); } } //遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key if (files != null) { int i = -1; for (File file : files) { i = i + 1; multipartBodyBuilder.addFormDataPart("image" + i, file.getName(), RequestBody.create(MediaType.parse("image/png"), file)); } } //构建请求体 RequestBody requestBody = multipartBodyBuilder.build(); Request.Builder RequestBuilder = new Request.Builder(); RequestBuilder.url(NetService.ufttt + reqUrl);// 添加URL地址 RequestBuilder.post(requestBody); String cookie =""; if (!StringUtlis.isEmpty(UserManager.getInstance().getToken())) { cookie = "token=" + UserManager.getInstance().getToken(); if (!StringUtlis.isEmpty(UserManager.getInstance().getUserId())) { cookie += ";uid=" + UserManager.getInstance().getUserId(); } } Request request = RequestBuilder.addHeader("Cookie",cookie).build(); Interceptor cacheInterceptor = new OfflineCacheControlInterceptor(); OkHttpClient okHttpClient=new OkHttpClient.Builder() .addNetworkInterceptor(cacheInterceptor) .retryOnConnectionFailure(true)//失败重连 .connectionPool(new ConnectionPool(5,8, TimeUnit.SECONDS)) .readTimeout(15, TimeUnit.SECONDS) .connectTimeout(15, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS) .readTimeout(15,TimeUnit.SECONDS) .build(); okHttpClient.newCall(request).enqueue(callback); //client.postJson(); } }
基本上使用就是这些,具体的https相关的实现,本人已经上传资源,下载地址
http://download.csdn.net/download/onlymetagain/10024542
相关文章推荐
- android Retrofit+OkHttp使用自制的证书实现https安全传输
- android中使用Retrofit调用https接口及缓存
- Android 百度地图开发(一)如何调用百度地图接口和在项目中显示百度地图以及实现定位
- Android使用Retrofit+OkHttp实现网络请求
- Android中okhttp3.4.1+retrofit2.1.0实现离线缓存
- Android(java)学习笔记229:服务(service)之绑定服务调用服务里面的方法 (采用接口隐藏代码内部实现)
- Android调用百度地图Web端接口,实现百度定位、导航
- Android Retrofit+Rxjava+MVP+EventBus+ButterKnife实现接口登录(无正则表达式)
- android使用ksoap2调用webservice接口实现电话号码查询功能
- retrofit2+okhttp3+rxjava2 实现通用的网络缓存(针对单个接口)
- Android调用百度地图Web端接口,实现百度定位、导航
- android app通过Geth RPC接口实现远程调用
- javaweb 服务器 提供SOAP协议接口,android客户端调用代码实现过程
- 一种类似Retrofit声明接口即可实现调用的WebApi客户端框架
- android Retrofit+OkHttp使用自制的证书实现https安全传输
- Android 使用Retrofit2.0 + OKHttp 实现 HTTP协议请求
- android app通过Geth RPC接口实现远程调用
- 在Android Native层直接调用MediaCodec接口的实现
- android自定义接口,然后在activity中实现点击监听,调用getView解决滑动错位的问题