奉上源码 - MvpApp,如果发现那里写的不对的,请好心人直接指出,我会努力去改正的。
主要包括:
- 简单的 get post请求、
- 统一请求头处理、
- 统一请求体处理、
- 单文件上传、
- 多文件上传、
- 一个key对用多个文件、
- 支持String转换器 不强制使用Gson转换器、
使用介绍 - get请求
- 路径替换
(1) 路径替换 主域名 http://api.qianguan360.com/service/ 接口地址 homePhone/loginPhone/ 登录接口 http://api.qianguan360.com/service/homePhone/loginPhone/13146008029-123456 {} 用花括号包裹的是动态字符串 用@Path进行注解,参数名字必须一致 @GET("homePhone/loginPhone/{phone}-{pwd}") Observable<LoginBean> loginQg(@Path("phone") String phone, @Path("pwd") String pwd);
- 添加请求行
主域名 http://192.168.4.39:8080/AlexApp/ 接口地址 login 登陆接口 http://192.168.4.39:8080/AlexApp/login?phone=13146008025&pwd=123456 key要和服务器的一致 @GET("login") Observable<LoginBean> loginGet1(@Query("phone") String phone, @Query("pwd") String pwd);
- 添加请求行
主域名 http://192.168.4.39:8080/AlexApp/ 接口地址 login 登陆接口 http://192.168.4.39:8080/AlexApp/login?phone=13146008025&pwd=123456 key要和服务器的一致 @GET("login") Observable<LoginBean> loginGet2(@QueryMap Map<String, String> params);
使用介绍 - post请求
主域名 http://192.168.4.39:8080/AlexApp/ 接口地址 login 登陆接口 http://192.168.191.3:4477/AlexApp/login 提交参数 phone pwd userLogo
- map方式提交
key要和服务器的一致 @POST("login") Observable<LoginBean> login(@Body Map<String, String> params);
- bean 方式提交
成员变量名要和后台一致 @POST("login") Observable<LoginBean> login(@Body UserBean bean);
- 多参数表单提交
key要和服务器的一致 @FormUrlEncoded @POST("login") Observable<LoginBean> login(@Field("phone") String phone, @Field("pwd") String pwd);
- 单文件上传
key要和服务器的一致 @Multipart @POST("upload") Observable<LoginBean> upLoad(@Part MultipartBody.Part userLogo, @Part("phone") RequestBody phoneBody, @Part("pwd") RequestBody pwdBody);MultipartBody.Part userLogo
RequestBody photoRequestBody = RequestBody.create(MediaType.parse("image/png"), file); MultipartBody.Part photo = MultipartBody.Part.createFormData("photo", file.getName(), photoRequestBody);RequestBody phoneBody
RequestBody phoneBody = RequestBody.create(MediaType.parse("text/plain"), phone); 或者 RequestBody phoneBody = RequestBody.create(null, phone);
- 一个key对应多个文件上传
key要和服务器的一致 @Multipart @POST("upload") Observable<String> upLoad2(@PartMap Map<String, RequestBody> params); Map<String, RequestBody> paramsMap = new HashMap<>(); for (int i = 0; i < fileList.size(); i++) { File file = fileList.get(i); RequestBody fileBody = RequestBody.create(MediaType.parse("image/png"), fileList.get(i)); paramsMap.put("userLogo\"; filename=\""+file.getName()+".png", fileBody); }
后端代码

Paste_Image.png
汤姆猫写到 E盘,好心人士如果发现我写错了,请告诉我。谢谢

Paste_Image.png
添加统一请求头
OkHttpClient okHttpClient = OkHttpUtil.getInstance(). headParams(new HeadParams() .addHeader("phoneNum", "13146008029") .addHeader("uuid", DeviceUtil.getSafeDeviceSoleId(App.getApp()))) .build();
添加统一请求体
OkHttpClient okHttpClient = OkHttpUtil.getInstance(). headParams(new StringParams() .addHeader("phoneNum", phone) .addHeader("uuid", DeviceUtil.getSafeDeviceSoleId(App.getApp())) .addBody("body0","body0") .addBody("body1","body1")) .level(HttpLoggingInterceptor.Level.BODY) .build();
使用String转换器
Retrofit retrofit = new Retrofit.Builder().baseUrl(HttpMan.doMainApi).client(okHttpClient) .addConverterFactory(StringConverterFactory.create())//添加 String 转换器 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加 RxJava 适配器 .build();
- OkHttpUtil.build()方法
package github.alex.okhttp; import android.util.Log; import java.io.File; import java.io.IOException; import java.util.Iterator; import java.util.Map; import java.util.concurrent.TimeUnit; import okhttp3.Cache; import okhttp3.FormBody; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.logging.HttpLoggingInterceptor; /** * Created by alex on 2016/6/22. * OkHttpUtil for Retrofit */ public class OkHttpUtil { private static OkHttpUtil instance; private static final String TAG = "#日志拦截器#"; private boolean debug = true; private HttpLoggingInterceptor.Logger logInterceptor; private StringParams headParams; private long connectTimeout; private long readTimeout; private long writeTimeout; private boolean retryOnConnectionFailure; private File cacheDir; private long cacheMaxSize; private HttpLoggingInterceptor.Level level; private String method; private OkHttpUtil() { cacheMaxSize = 1024 * 1024 * 100; level = HttpLoggingInterceptor.Level.BASIC; debug = true; method = "POST"; } /** * 单例模式 获取 OkHttpUtil */ public static OkHttpUtil getInstance() { if (instance == null) { synchronized (OkHttpUtil.class) { instance = (instance == null) ? new OkHttpUtil() : instance; } } return instance; } /** * 设置 日志 拦截器 */ public OkHttpUtil httpLoggingInterceptor(HttpLoggingInterceptor.Logger logInterceptor) { this.logInterceptor = logInterceptor; return this; } /** * 设置请求头 */ public OkHttpUtil headParams(StringParams headParams) { this.headParams = headParams; return this; } /** * 设置连接超时时间 */ public OkHttpUtil connectTimeout(long connectTimeout) { this.connectTimeout = connectTimeout; return this; } /** * 设置读取超时时间 */ public OkHttpUtil readTimeout(long readTimeout) { this.readTimeout = readTimeout; return this; } /** * 设置写入超时时间 */ public OkHttpUtil writeTimeout(long writeTimeout) { this.writeTimeout = writeTimeout; return this; } /** * 连接失败自动重试 */ public OkHttpUtil retryOnConnectionFailure(boolean retryOnConnectionFailure) { this.retryOnConnectionFailure = retryOnConnectionFailure; return this; } /** * 设置缓存路径 */ public OkHttpUtil cacheDir(File cacheDir) { this.cacheDir = cacheDir; return this; } /** * 设置缓存大小 */ public OkHttpUtil cacheMaxSize(long cacheMaxSize) { this.cacheMaxSize = cacheMaxSize; return this; } /**设置log的等级*/ public OkHttpUtil level(HttpLoggingInterceptor.Level level){ this.level = level; return this; } /**设置处于 debug */ public OkHttpUtil debug(boolean debug){ this.debug = debug; return this; } /**设置请求方法*/ public OkHttpUtil method(String method){ this.method = method; return this; } /** * 得到 OkHttpClient 对象 */ public OkHttpClient build() { OkHttpClient.Builder builder = new OkHttpClient.Builder(); if (debug) { // Log信息拦截器 HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { @Override public void log(String message) { Log.e(TAG, message); if (logInterceptor != null) { logInterceptor.log(message); } } }); loggingInterceptor.setLevel(level); /*要在 OkHttpClient.Builder().build(); 之前,否则日志出不来*/ builder.addInterceptor(loggingInterceptor); } if (headParams != null) { builder.addInterceptor(new HeadInterceptor(headParams)); } if (cacheDir != null) { if (cacheMaxSize < 0) { cacheMaxSize = 1024 * 1024 * 128; } Cache cache = new Cache(cacheDir, cacheMaxSize); builder.cache(cache); } OkHttpClient okHttpClient = builder.build(); OkHttpClient.Builder newBuilder = okHttpClient.newBuilder(); if (connectTimeout > 0) { newBuilder.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS); } if (readTimeout > 0) { newBuilder.readTimeout(readTimeout, TimeUnit.MILLISECONDS); } if (writeTimeout > 0) { newBuilder.writeTimeout(writeTimeout, TimeUnit.MILLISECONDS); } newBuilder.retryOnConnectionFailure(retryOnConnectionFailure); return okHttpClient; } final class HeadInterceptor implements Interceptor { private StringParams stringParams; public HeadInterceptor(StringParams headParams) { this.stringParams = headParams; } @Override public Response intercept(Chain chain) throws IOException { Request.Builder requestBuilder = chain.request().newBuilder().addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").addHeader("Accept-Encoding", "gzip, deflate").addHeader("Connection", "keep-alive").addHeader("Accept", "*/*"); Map<String, String> stringHeadMap = stringParams.getHeadMap(); Map<String, String> stringBodyMap = stringParams.getBodyMap(); /*解析文本请求头*/ if ((stringHeadMap != null) && (stringHeadMap.size() > 0)) { Iterator<?> iterator = stringHeadMap.entrySet().iterator(); while (iterator.hasNext()) { @SuppressWarnings("rawtypes") Map.Entry entry = (Map.Entry) iterator.next(); requestBuilder.addHeader(entry.getKey() + "", entry.getValue() + ""); } } RequestBody requestBody = getStringRequestBody(stringBodyMap); if(requestBody!=null){ requestBuilder.method(method, requestBody); } return chain.proceed(requestBuilder.build()); } } /** * 添加文本请求体参数 */ @SuppressWarnings("rawtypes") private RequestBody getStringRequestBody(Map<?, ?> stringBodyMap) { FormBody.Builder multipartBodyBuilder = new FormBody.Builder(); if ((stringBodyMap == null) || (stringBodyMap.size() <= 0)) { return null; } if ((stringBodyMap == null) || (stringBodyMap.size() <= 0)) { return null; } /*解析文本请求体*/ if ((stringBodyMap != null) && (stringBodyMap.size() > 0)) { Iterator iterator = stringBodyMap.entrySet().iterator(); while (iterator.hasNext()) { java.util.Map.Entry entry = (java.util.Map.Entry) iterator.next(); multipartBodyBuilder.add(entry.getKey() + "", entry.getValue() + ""); } } return multipartBodyBuilder.build(); } }
- HeadParams
package github.alex.okhttp; import android.support.annotation.NonNull; import java.util.LinkedHashMap; import java.util.Map; /** * Created by alex on 2016/6/22. */ public class StringParams { /** * 文本请求头 */ private Map<String, String> stringHeadMap; /** * 文本请求体 */ private Map<String, String> stringBodyMap; public StringParams() { this.stringBodyMap = new LinkedHashMap<String, String>(); this.stringHeadMap = new LinkedHashMap<String, String>(); } /** * 添加文本请求体 */ public StringParams addHeader(@NonNull String key, @NonNull String value) { stringHeadMap.put(key, value); return this; } /** * 添加文本请求体 */ public StringParams addBody(@NonNull String key, @NonNull String value) { stringBodyMap.put(key, value); return this; } /** * 获取请求头参数 */ public Map<String, String> getHeadMap(){ return stringHeadMap; } /** * 获取请求头体参数 */ public Map<String, String> getBodyMap(){ return stringBodyMap; } }
文/Alex_Cin(简书作者)
原文链接:http://www.jianshu.com/p/14e09c84869a
原文链接:http://www.jianshu.com/p/14e09c84869a