Retrofit之多⽂件多参数上传
Android 移动开发当中免不了要访问⽹络,访问⽹络的⽅式相信每个⼈都会有⾃⼰不同的⽅法,你可以⾃⼰封装⽹络请求,也可以⽤⽹上别⼈开源的框架。如果开源的框架当中,⽬前最受欢迎的可要数Retrofit了,⽽使⽤Retrofit中最⿇烦也就是上传图⽚或者⽂件了,本⽂就对如何使⽤Retrofit同时上传多参数和多图⽚⽂件做详细的演⽰,并贴出相应实例代码。
在正式本⽂的讲解之前,先说明⼀下,基于现在RxJava也⽕得不要不要的,所以本⽂就结合RxJava和Retrofit⼀起来说明他的⽤法。
1.第⼀步:导包
现在的导包⽅式基本都使⽤Maven⾃动导包了,所以我们选择下⾯的⽅式⽽不⽤再去下载jar然后再导⼊。在Module的adle⽂件中添加如下的依赖
compile ‘io.reactivex:rxjava:1.2.9’
compile ‘io.reactivex:rxandroid:1.2.1’
compile ‘fit2:adapter-rxjava:2.0.0’
compile ‘fit2:retrofit:2.2.0’
compile ‘fit2:converter-gson:2.2.0’
compile ‘com.squareup.okhttp3:okhttp:3.6.0’
2.第⼆步:构造你的Retrofit公共管理者
package com.yuanyi.logistics.manager;
import com.stant.Constants;
import urrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import java.RxJavaCallAdapterFactory;
verter.gson.GsonConverterFactory;
/**
* Created by AHuan on 2017/4/24.
*/
public class RetrofitManager {
private static RetrofitManager mRetrofitManager;
private Retrofit mRetrofit;
private RetrofitManager(){
initRetrofit();
}
//获取同步静态对象
public static synchronized RetrofitManager getInstance(){
if(mRetrofitManager==null){
mRetrofitManager=new RetrofitManager();
}
return mRetrofitManager;
}
private void initRetrofit(){
HttpLoggingInterceptor httpLoggingInterceptor=new HttpLoggingInterceptor();    httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient.Builder builder=new OkHttpClient.Builder();
//添加过滤器
builder.addInterceptor(httpLoggingInterceptor);
//设置连接超时时间
//设置读取超时时间
//设置写超时时间
builder.writeTimeout(20,TimeUnit.SECONDS);
//设置超时重连
OkHttpClient client=builder.build();
mRetrofit=new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.
ate())
.ate())
.client(client)
.build();
}
public <T> T creatReq(Class<T> reqServer){
ate(reqServer);
}
}
3.编写请求接⼝
package com.yuanyi.logisticswork.api;
import com.yuanyi.logistics.bean.AppUpdateBean;
import com.yuanyi.logistics.bean.ResponseBean;
import com.yuanyi.logistics.bean.StorageBean;
import com.yuanyi.logistics.bean.TaskBean;
import com.yuanyi.logistics.bean.User;
import java.util.List;
import java.util.Map;
import okhttp3.RequestBody;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.PartMap;
import retrofit2.http.Query;
import rx.Observable;android retrofit
/**
* Created by AHuan on 2017/4/22.
*/
public interface TaskApi {
//获取司机的任务列表
/**
* 使⽤post⽅法,查询参数声明字段是userId
* @param userId
* @return
*/
@FormUrlEncoded
@POST("vehicleInspectionApi/find")
Observable<TaskBean> getTask(@Field("userId") String userId );
//获取正在任务中的司机列表
@POST("billListApi/getBydriverUserId")
Observable<List<User>> getDrivers();
//提交问题操作接⼝
/
**
* 实现多参数post请求
* @param dataMap
* @return
*/
@FormUrlEncoded
@POST("billListApi/ updateProblemGoods")
Observable<ResponseBean> updateProblemGoods(@FieldMap Map<String,String> dataMap);
//检测版本更新信息
@POST("editionApi/editionNo")
Observable<AppUpdateBean> getUpdateInfo();
/
/获取搬仓的货物信息
@FormUrlEncoded
@POST("subaru_Parts/storageCarry/getByStorage")
Observable<StorageBean> getStorageInfo(@Field("partNo") String partNo);
//提交搬仓上传的货物信息
@FormUrlEncoded
@POST("subaru_Parts/storageCarry/update")
Observable<ResponseBean> submitStorage(@FieldMap Map<String,String> dataMap);
//上传加油数据
/**
* 实现多图⽚⽂件多参数上传
* @param params
* @return
*/
@Multipart
@POST("vehicleInspectionApi/updateOliApi")
Observable<ResponseBean> uploadAddOil(@PartMap Map<String, RequestBody> params);
/**
* get⽅法,@Query("Id")表⽰在Url后⾯追加字段是id的内容,后⾯的如此类推
* @param id
* @param passwords
* @param Pass
* @return
*/
@FormUrlEncoded
@GET("userApi/updateApiPass")
Observable<ResponseBean> changePw(@Query("id") int id, @Query("passwords") String passwords, @Query("Pass") String Pass); }
4.编写⼯具类
编写⼀个专门⽤来⽣成Map的⼯具类。
我们以上⾯中的 Observable uploadAddOil();这个⽅法为例。
package com.yuanyi.logistics.utils;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import okhttp3.MediaType;
import okhttp3.RequestBody;
/**
* Created by AHuan on 2017/12/11.
* ⽣成Retrofit的多参数和多⽂件多图⽚的构造参数map
*/
public class RetrofitRequestBodyUtil {
/**
*使⽤的时候传进来的Map的构造为Map<String,Object>,如果传的是普通字符串参数的话,就往map⾥⾯put<String,String>
*如果传递的是图⽚或者的话,就put<String,File[]>, key对应的是服务端所要的参数字段名,File[] 所对应的是上传的⽂件数组
* 例如服务器需要的是下⾯的参数  @RequestParam(value = "files") MultipartFile[] postedFiles
* 我们的map中就需要put("files",File[]);
* @param resourceMap
* @return
*/
public static Map<String, RequestBody> getRequestBodyMap(Map<String,Object> resourceMap){
Map<String, RequestBody> params=new HashMap<>();
Iterator Set().iterator();
while (iterator.hasNext()){
Map.Entry entry= (Map.Entry) ();
Value() instanceof String){
//判断值如果是String的话就直接put进去
RequestBody ate(MediaType.parse("text/plain;charset=UTF-8"),(Value());
params.put((Key(),body);
}else Value() instanceof File){
//判断当前值是单个⽂件的话就把key设置成服务端所要的参数⼦端名加⽂件名,具体格式可以看下⾯的
RequestBody ate(MediaType.parse("multipart/form-data;charset=UTF-8"),(Value());            params.put((Key()+"\";filename=\""+((Value()).getName()+"",body);
}else Value() instanceof File[]){
//判断当前的值是⽂件数组的话,要把⼀个个⽂件拆开再put进去
File[] files= (File[]) Value();
if(files!=null && files.length>0){
for(File f : files){
RequestBody ate(MediaType.parse("multipart/form-data;charset=UTF-8"),f);
params.put((Key()+"\";filename=\""+f.getName()+"",body);
}
}
}
}
return params;
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。