使用Retrofit搭建自己的网络请求框架

相关文章:

Retrofit2与RxJava用法大全

RxJava2+Retrofit2实现网络请求和解析封装

给 Android 开发者的 RxJava 详解

Android RxJava2+Retrofit2搭建网络请求框架

Retrofit2+Rxjava2之优雅的封装

Retrofit — 用实现Basic Authentication(2)

HTTP使用BASIC认证的原理及实现方法


1、Retrofit入门介绍

Retrofit作为现在最流行的联网框架,公司项目中基本全部使用的它,当然网上有很多详细的教程讲解retrofit的使用,我只是结合自己在项目中的使用情况做一下记录,以便自己日后使用。

1.1 项目引入

  compile 'io.reactivex:rxjava:1.1.0'
  compile 'io.reactivex:rxandroid:1.1.0'
  compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
  compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
  compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'

1.2 官方教程链接

http://square.github.io/retrofit/

1.3 使用

  • 1. 创建Retrofit实例时需要通过Retrofit.Builder,并调用baseUrl方法设置URL。
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://localhost:4567/")
        .build();

2、定义的service返回值为Call的情况

2.1、 Retrofit初始化

 public static final String baseUrl = "http://192.168.100.214:8090/peakBusiness/";  //内网
 public static final String imgUrl = "http://192.168.100.214:8686/FYmanage/";  //内网--图片
   //--接口请求 
   private static NetworkService api;
    public static NetworkService api() {
        if (api == null) {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            api = retrofit.create(NetworkService.class);
        }
        return api;
    }
  //---上传图片
  private static NetworkService apiUpload;
    public static NetworkService apiUpload() {
        if (apiUpload == null) {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(imgUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            apiUpload = retrofit.create(NetworkService.class);
        }
        return apiUpload;
    }

2.2、 Retrofit接口方法

我们定义的service返回值为Call的情况。
示例:

 //提交投诉或意见
    @GET("front/user.htm")
    Call<ReceiveData.BaseResponse>  upUserBack(@QueryMap Map<String, String> options);

    //上传图片
    @Multipart
    @POST("uploadImg.html")
    Call<ReceiveData.UpPhotoResponse> uploadPic(@QueryMap Map<String, String> options, @PartMap Map<String, RequestBody> params);

2.3、 Retrofit返回数据解析

  //基础数据的返回
    public static class BaseResponse {
        public int code;
        public String msg;
    }

 //上传头像
    public static class UpPhotoResponse {
        public String code;
        public String status;
        public ArrayList<PiclistBean> piclist;
    }

3、定义的service返回值为Observable 的情况

3.1、 Retrofit初始化

HttpMethods.java

public static final String BASE_URL = "http://192.168.100.132:8080/cnbsExamInterface/";
    private static final int DEFAULT_TIMEOUT = 15;
    private NetworkService networkService;
    public static final int SuccessCode = 0;
   private String username = "user";
    private String password = "123";
    // basic认证信息 
    String credentials = username + ":" + password;
    final String basic = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
    //构造方法私有,添加一个拦截器
    private HttpMethods() {
        OkHttpClient httpClient = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request.Builder builder = chain.request().newBuilder();
                        builder.addHeader("Authorization", basic);
                        return chain.proceed(builder.build());
                    }
                })
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .build();

        networkService = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(httpClient)
                .build()
                .create(NetworkService.class);
    }

    //在访问HttpMethods时创建单例
    private static class SingletonHolder {
        private static final HttpMethods INSTANCE = new HttpMethods();
    }

    //获取单例
    public static HttpMethods getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private void toSubscribe(Observable o, Subscriber s) {
        o.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
                .subscribe(s);
    }
    /**
     * 下面是请求方法*/
    public void base(Subscriber<HttpResult.BaseResponse> subscriber, Map<String, String> options) {
        Observable observable = networkService.base(options);
        toSubscribe(observable, subscriber);
    }

  //智能组卷 --zuo
    public void autoMakeExam(Subscriber<HttpResult.BaseResponse<MakeExamBean>> subscriber, Map<String, String> options) {
        Observable observable = networkService.autoMakeExam(options);
        toSubscribe(observable, subscriber);
    }

    //提交考试信息 --zuo
    public void submitExamData(Subscriber<HttpResult.BaseMsgResponse> subscriber, Map<String, String> options, Map<String, RequestBody> params) {
        Observable observable = networkService.submitExamData(options,params);
        toSubscribe(observable, subscriber);
    }

3.2、 请发起求的Service

NetworkService.java


    //智能组卷  --zuo
    @GET("examAct/intelligencePaperAnswer.html")
    Observable<HttpResult.BaseResponse<MakeExamBean>> autoMakeExam(@QueryMap Map<String, String> options);

    //提交考试信息  --zuo
    @Multipart
    @POST("examAct/addUserExam.html")
    Observable<HttpResult.BaseMsgResponse> submitExamData(@QueryMap Map<String, String> options, @PartMap Map<String, RequestBody> params);

3.3、 Retrofit返回数据解析

HttpResult.java

   public static class BaseResponse<T> {
        public int code;
        public String msg;
        public T obj;
    }

  public static class BranchResponse{
        public int code;
        public String msg;
        public List<String> list;
    }

3.4、 Retrofit使用

private void login(String userId, String password) {
        Map<String, String>  map = new HashMap<>();
        map.put("userId",userId);
        map.put("password",password);
         HttpMethods.getInstance().base(new Subscriber<HttpResult.BaseResponse>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(HttpResult.BaseResponse baseResponse) {

            }
        },map);

    }

4、Retrofit结合RxJava处理嵌套请求

4.1 Observable模式下的Retrofit实例化

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(baseUrl)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();

4.2 Observable模式下的请求接口

我们定义的service返回值就不在是一个Call了,而是一个Observable:

public interface NetworkService {
@GET("uploadImg.html")
Observable<Bean> uploadPic(@QueryMap Map<String, String> options);
}

4.3 进行网络请求

Map<String, String> options = new HashMap<>();
options.put("key", "value");
RestClient.mapi().request(options)
  .subscribeOn(Schedulers.io())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(new Subscriber<Bean>() {
       @Override
       public void onCompleted() {
                    //----
          }
       @Override
       public void onError(Throwable e) {
                   //---                 
 }
       @Override
       public void onNext(MovieEntity movieEntity) {
                   //----
         }
   });

4.4 嵌套网络请求

这里就要用到RxJava的操作符flatMap了。Demo代码如下:

Map<String, String> options = new HashMap<>();
options.put("type", "userHeadImg");
Map<String, RequestBody> obj = new HashMap<>();
RequestBody photo = RequestBody.create(MediaType.parse("image/png"), os.toByteArray());
obj.put("Imgs\"; filename=\"icon.png",  photo);
RestClient.oapi().oUploadPic(options,obj)
                 .flatMap(new Func1<ReceiveData.OUpPhotoResponse, Observable<ReceiveData.OBaseResponse>>() {
                  @Override
                  public Observable<ReceiveData.OBaseResponse> call(ReceiveData.OUpPhotoResponse oUpPhotoResponse) {
                    thumPath = oUpPhotoResponse.piclist.get(0).getImg_path();
                    Map<String, String> options = new HashMap<>();
                    options.put("method", "updateImg");
                    options.put("userId", 5+"");
                    options.put("headImg",thumPath);
                    return RestClient.omapi().oResetUserImg(options);
                    }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Action1<ReceiveData.OBaseResponse>() {
                    @Override
                    public void call(ReceiveData.OBaseResponse oBaseResponse) {
                        if (oBaseResponse.code == 0){
                            showInfo.setText("嵌套请求成功!!");
                            userimg.setImageURI(RestClient.imgUrl+thumPath);
                        }
                    }
                }); 

5、 其他工具类

拦截器InterceptorUtils.java

public class InterceptorUtils{
    public static String TAG = "zuo";
    //日志拦截器
    public static Interceptor LogInterceptor() {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                LogUtils.i(TAG, String.format("接口请求 %s on %s%n%s", request.url(), chain.connection(), request.headers()));
                return chain.proceed(request);

            }
        };
    }

    //给请求添加一个头
    public static Interceptor HeaderInterceptor() {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request.Builder builder = chain.request().newBuilder();
                builder.addHeader("token", "zuo");
                return chain.proceed(builder.build());
            }
        };

    }

}

日志工具类LogUtils.java

/**
 * 日志打印工具类,
 * 应用正式上线的时候,需要把LEVEL设置为NOTHING
 * author: zuo
 * date: 2017/12/5 19:05
 */

public class LogUtils {
    public static final int VERBOSE = 1;
    public static final int DEBUG = 2;
    public static final int INFO = 3;
    public static final int WARN = 4;
    public static final int ERROR = 5;
    public static final int NOTHING = 6;
    public static final int LEVEL = VERBOSE;

    public static void v(String tag, String msg) {
        if (LEVEL <= VERBOSE) {
            Log.v(tag, msg);
        }
    }

    public static void d(String tag, String msg) {
        if (LEVEL <= DEBUG) {
            Log.d(tag, msg);
        }
    }

    public static void i(String tag, String msg) {
        if (LEVEL <= INFO) {
            Log.i(tag, msg);
        }
    }

    public static void w(String tag, String msg) {
        if (LEVEL <= WARN) {
            Log.w(tag, msg);
        }
    }

    public static void e(String tag, String msg) {
        if (LEVEL <= ERROR) {
            Log.e(tag, msg);
        }
    }

}

6、 Basic认证

有两种添加方式,一种是在每一个接口中加;第二种是在拦截器中加


6-0、 认证信息加密

// 认证信息用Base64编码
String credentials = username + ":" + password;
final String basic =
        "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);

6-1、 在接口中加basic认证

这样就是在每次调用接口时都需要传6-0的(String )basic

 @GET("loginAct/loginByVerifyCode.html")
 Observable<HttpResult.BaseResponse> base(@Header("Authorization") String auth,@QueryMap Map<String, String> options);

6-2、 在拦截器中加basic认证

在拦截器中加的话就简单一点,不需要每个接口都传一遍,这个工作就由拦截器去做了。

public class InterceptorUtils{
    public static String TAG = "zuo";
    //日志拦截器
    public static Interceptor LogInterceptor(final String basic) {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request();
                Request.Builder builder = request.newBuilder();
                builder.addHeader("Authorization", basic);
                LogUtils.i(TAG, String.format("接口请求 %s on %s%n%s", request.url(), chain.connection(), request.headers()));
                return chain.proceed(builder.build());

            }
        };
    }

    //给请求添加一个头
    public static Interceptor HeaderInterceptor(final String basic) {
        return new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request.Builder builder = chain.request().newBuilder();
                builder.addHeader("Authorization", basic);
//                builder.addHeader("token", "zuo");
                return chain.proceed(builder.build());
            }
        };

    }

}
/**
 * 封装Retrofit的请求
 *
 * @author zuo
 * @date 2017/12/5 16:43
 */
public class HttpMethods {
    public static final String BASE_URL = "http://192.168.100.132:8080/cnbsExamInterface/";
    private static final int DEFAULT_TIMEOUT = 15;
    private NetworkService networkService;
    public static final int SuccessCode = 0;
    private String username = "user";
    private String password = "123";
    // basic认证信息
    String credentials = username + ":" + password;
    final String basic = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
    //构造方法私有
    private HttpMethods() {
        OkHttpClient httpClient = new OkHttpClient.Builder()
                .addInterceptor(InterceptorUtils.LogInterceptor(basic))
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .build();

        networkService = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .client(httpClient)
                .build()
                .create(NetworkService.class);
    }

    //在访问HttpMethods时创建单例
    private static class SingletonHolder {
        private static final HttpMethods INSTANCE = new HttpMethods();
    }

    //获取单例
    public static HttpMethods getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private void toSubscribe(Observable o, Subscriber s) {
        o.subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
                .subscribe(s);
    }

    //----------请求方法------------
    public void base(Subscriber<HttpResult.BaseResponse> subscriber, Map<String, String> options) {
        Observable observable = networkService.base(options);
        toSubscribe(observable,subscriber);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值