Http二次封装思路

本文介绍了在Android开发中对Http请求的二次封装过程,包括HttpConfig的配置、OkhttpEngine的实现、请求和响应的处理、本地缓存策略以及如何处理不同类型的数据。通过自定义Http请求入口类,实现了同步和异步请求,并支持取消请求、数据转换和本地缓存功能。
摘要由CSDN通过智能技术生成

用过了现有的一些http请求框架,决定自己也来简单的封装一个。本文只是基于一些http请求框架二次封装的,高手勿喷。源码

http的请求和响应

一个http的请求通常包含请求头、请求体、响应头和响应体,考虑到这些因素,HttpConfigApiResponse就诞生了。HttpConfig

HttpConfig

http参数配置类,应该包含如下属性:

  • baseUrl/url

    如果使用restful形式,baseUrl是不能为空并且url为业务path, 如果是非restful,url必须为请求全路径

  • GET/POST

    有了url,接下来需要有请求的方法类型,由于我这边只用到了GETPOST,所以只对此做了封装。

    特别说明: POST 有三种提交方式(form表单、json形式和 复杂形式)

FORM_DATA("application/x-www-form-urlencoded;charset=utf-8"),
JSON_DATA("application/json;charset=utf-8"),
MULTI_PART_DATA("multipart/form-data;charset=utf-8");
  • headers

    http的请求头封装,采用(Map<String,String>)集合

  • params

    http的请求参数,采用(Map<String,Object>)如果请求方法是GET形式,那么采用拼接字符串的形式将参数拼接到url中; 如果请求方法是POST形式,则需要根据提交参数的方式不同,会有不同的请求体。

  • cacheStrategy

    考虑到App的使用交互和服务器减压,我们要考虑有一些请求可以做一些缓存,那么常用的缓存策略有CACHE_ONLYCACHE_FIRSTNET_ONLYNET_CACHE

  • type

    type是响应数据的type,这个主要用在Http请求结果返回后将json转为bean对象的映射类型,需要考虑泛型和非泛型(Class和ParamizableType)

  • tag

    给每一个请求链接打一个标签,可用于一些其它的操作,如根据tag取消请求

  • isAsync

    当前请求是同步执行还是异步执行的标志,异步执行会在子线程中进行http请求,同步执行在当前线程中执行http请求。

ApiResponse

使用ApiResponse的原因是为了规范请求结果返回的表现形式,他有一个T类型的数据。

  • code

    状态码,与http请求响应状态码一致,200~300 请求成功,304 使用缓存

  • message

    请求响应的错误信息

  • data

    响应的数据,泛型T, 根据httpConfig中的type,映射 json–> bean

Http引擎

IHttpEngine是一个接口,使用者可以根据实际的情况做具体的实现。

public interface IHttpEngine {
   

    // 开始执行 http请求
    <T> execute(HttpConfig config, MultableLiveData<ApiResponse<T>> liveData);
    // 根据tag取消
    void cancel(Object tag);
}

由于http请求有同步和异步两种情况并且又牵扯到了缓存策略问题(如果先进行缓存返回在执行网络请求并返回数据),在异步回调的情况下这些问题可以通过回调解决,但是在同步情况下,这些问题并不能很好的处理,曾经有使用过将当前请求clone,然后再次调用请求服务器的方法,但是在使用过jetpackLiveData框架后这些问题都可以解决了。

OkhttpEngine

Android开发目前来说大多数项目使用的都是Okhttp来做请求,本次我使用的默认引擎也是使用它来作为默认的实现。OkHttpEngine

okhttp简单配置

对okhttp进行一些简单的配置就可以进行网络请求了,如下:

  • 创建okHttpClient
 private static final OkHttpClient OK_HTTP_CLIENT;

 // 添加日志拦截器
 HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
 loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

 OK_HTTP_CLIENT = new OkHttpClient.Builder()
               .connectTimeout(15, TimeUnit.SECONDS)
               .readTimeout(15, TimeUnit.SECONDS)
               .writeTimeout(15, TimeUnit.SECONDS)
               .addInterceptor(loggingInterceptor)
               .build();
  • 添加证书管理
TrustManager[] trustManagers = new TrustManager[]{
   
    new X509TrustManager() {
   
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
   }
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
   }
        @Override
        public X509Certificate[] getAcceptedIssuers() {
   
            return new X509Certificate[0];
        }
     }
};

SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustManagers, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);

实现Http请求

IHttpEngine中的execute方法是具体的http请求方法,所有实现IHttpEngine的方法都需要实现此方法。

@NonNull
@Override
public <T> void execute(@NonNull Config config, 
                        @NonNull MutableLiveData<ApiResponse<T>> liveData) {
   
    Request request = generateRequest(config);
    Call call = OK_HTTP_CLIENT.newCall(request);
    if (!config.isAsync) {
   
        execute(call, config, liveData);
    } else {
   
        enqueue(call, config, liveData);
    }
}

execute方法中大致需要做以下事:

  • 创建request–> genearteRequest
  • 发送http请求 —> execute/enqueue
创建httpRequest

generateRequest()根据HttpConfig中的请求方式来创建不同的http请求。

/**
 * 根据配置信息生成request
 *
 * @param config 配置信息
 * @return request
 */
 @NonNull
 private Request generateRequest(@NonNull Config config) {
   
    switch (config.method) {
   
       case Config.GET:
           return generateGetRequest(config);
       case Config.POST:
           return generatePostRequest(config);

       default:
           throw new IllegalStateException("this request method invalidate: " + config.method);
    }
}
GET请求的创建方式

genearteGetReques()方法,利用okhttp的Request类创建request实例,并利用UrlCreator将参数拼接到url中。Url拼接时需要注意使用UrlEncoder编码,不然可能会造成服务器和客户端解析数据不一致的情况。

/**
 * 生成get方式的请求
 *
 * @param config 请求配置
 * @return 返回get方式的request
 */
@NonNull
private Request generateGetRequest(@NonNull Config config) {
   
   Request.Builder builder = new Request.Builder().get();
   builder.tag(config.tag);
   addHeader
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值