okhttp的拦截和封装

一、目录

二、 OkHttp拦截器概述

OKHttp中,Interceptors拦截器是一种强大的机制,可以监视,重写和重试Call实例

1.OkHttp的拦截器的作用

1.拦截器可以一次性对所有请求的返回值修改

2.拦截器可以一次性对请求的参数和返回的结果进行编码,比如统一设置为UTF-8

3.拦截器可以对所有的请求做统一的日志处理,不需要在每个请求开始或者结束的位置都添加一个日志操作。

4.其他需要对请求和返回进行统一处理的需求…

2.OkHttp拦截器的分类

OkHttp中的拦截器分2个:APP层面的拦截器(Application Interception)网络请求层面的拦截器(Network Interception)。

3.两种区别

Application:

1.不需要担心是否影响OKHttp的请求策略和请求速度

2.即使从缓存中取数据,也会执行Application拦截器

3.允许重试,即Chain.proceed()可以执行多次

4.可以监听观察这个请求的最原始的为改变的意图(请求头,请求体等)无法操作OKHttp为我们自动添加额外的请求头

5.无法操作中间的响应结果,比如当URL重定向发生以及请求重试,只能操作客户端主动第一次请求以及最终的响应结果

Network Interceptors

1.可以修改OKHttp框架自动添加的一些属性,与允许操作中间响应,比如当请求操作发生重定向或者重试等

2.可以观察最终完整的请求参数(也就是最终服务器接收到的请求数据和数据)

三、两种拦截器的实例

1.实例化appInterceptor拦截器

Interceptor appInterceptor = new Interceptor(){
		public Response intercept(Chain chain) throws IOException{
				Request request = chain.request();
				HttpUrl url = request.url();
				String s = url.url().toString();

				Log.d(TAG,"app intercept:begin");
				Response response = chain.proceed(request);
				Log.d(TAG,:"app intercept:end");
				return response;
				}
		};

2.实例化networkInterceptor拦截器

Interceptor networkInterceptor = new Interceptor(){
				public Response intercept(Chain chain) throws IOException{
					Request request = chain.request();
					Log.d(TAG,"network interceptor:begin");
					Response response = chain.proceed(request);
					Log.d(TAG,"network interceptor:end");
					return response;
					}
				};

3.将两个拦截器配置在Client中,并发送请求

	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		okHttpClient = new OKHttpClient
							.Builder()
							.addInterceptor(appInterceptor)
							.addNetworkInterceptor(networkInterceptor)
							.build();
		Button button = (Button)findViewById(R.id.bt);
		button.setOnClickListener(new View.OnclickListener(){
			public void onClick(View v){
				Request request = new Request.Builder()
											.url("http://www.baidu.cn")
											.build();
				okHttpClient.newCall(request).enqueue(new Callback(){
				public void onFailure(Call call, IOException e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        Log.d(TAG,"--" + response.networkResponse());
                    }
                });
            }
        });

4.运行结果

在这里插入图片描述

四、拦截器的实际应用

1.统一添加Header

应用场景:后台要求在请求API时,在每个接口的请求头添加上对于的Token这时候就可以使用拦截器对他们进行统一的配置

Interceptor TokenHeaderInterceptor = new Interceptor(){
	public Response intercept(Chain chain) throws IOException{
			String token = Appservice.getToken();
			Request originalRequest = chain.request();
			Request updataRequest = originalRequest.newBuilder()
			.header("token",token)
			.build();
			return chain.proceed(updateRequest);
			}
		};

在OKHttpClient中配置

okHttp = new OKHttpClient
			.Builder()
			.addInterector(TokenHeaderInterceptor)
			.addNetworkInterceptor(networkInterceptor)
			.build();
Button button =(Button)findViewById(R.id.bt);
button.setOnClientListener(new View.onClientListener(){
		public void onClick(View v){
			Request request = new Request.Builder
							.url("http://www.baidu.cn")
							.build();
			okHttpClient.newCall(request).enqueue(new Callback(){
			 public void onFailure(Call call, IOException e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        Log.d(TAG, "--" + response.networkResponse());
                    }
                });
            }
        });

2.改变请求体

应用场景:在上面的login接口基础上,后台要求我们传过去的请求参数是按照一定规则经过加密的。

规则:
请求参数名统一为content;
content值:JSON格式的字符串经过AES加密后的内容;

实例化拦截器

Interceptor RequestEncryptInterceptor = new Interceptor() {
		private static final String FORM_NAME = "content";
		private static final String CHARSET="UTF-8";
		public Response intercept(chain chain) throws IOException{
				Request request = chain.request();
				Requestbody body=request.body();
				if(body instanceof FormBody){
						FormBody formBody = (FormBody)body;
						Map<String,String> formMap=new HashMap<>();
						for(int i=0;i<formBody.size();i++){
							formMap.put(formBody,name(i),formBody.value(i));
							}
						Gson gson=new Gson();
						String jsonParams=gson.toJson(formMap);
						String encrytParams = AESCrytUtils.encrypt(jsonParams.getBytes(CHARSET),AppConstant.getAESKey());
						body=new FormBody.Builder().add(FORM_NAME,encryptParams).build();
				}
			if(body!=null)
			{
				request = request,newBuilder()
							.post(body)
							.build();
			}
	return chain.proceed(request);
	}
};												

五、OkHttp的封装

1.封装

public class NetRequest {
    private static NetRequest netRequest;
    private static OkHttpClient okHttpClient; // OKHttp网络请求
    private Handler mHandler;

    private NetRequest() {
        // 初始化okhttp 创建一个OKHttpClient对象,一个app里最好实例化一个此对象
        okHttpClient = new OkHttpClient();
        okHttpClient.newBuilder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(10, TimeUnit.SECONDS);
        mHandler = new Handler(Looper.getMainLooper());
    }

    /**
     * 单例模式  获取NetRequest实例
     *
     * @return netRequest
     */
    private static NetRequest getInstance() {
        if (netRequest == null) {
            netRequest = new NetRequest();
        }
        return netRequest;
    }

    //-------------对外提供的方法Start--------------------------------

    /**
     * 建立网络框架,获取网络数据,异步get请求(Form)
     *
     * @param url      url
     * @param params   key value
     * @param callBack data
     */
    public static void getFormRequest(String url, Map<String, String> params, DataCallBack callBack) {
        getInstance().inner_getFormAsync(url, params, callBack);
    }

    /**
     * 建立网络框架,获取网络数据,异步post请求(Form)
     *
     * @param url      url
     * @param params   key value
     * @param callBack data
     */
    public static void postFormRequest(String url, Map<String, String> params, DataCallBack callBack) {
        getInstance().inner_postFormAsync(url, params, callBack);
    }

    /**
     * 建立网络框架,获取网络数据,异步post请求(json)
     *
     * @param url      url
     * @param params   key value
     * @param callBack data
     */
    public static void postJsonRequest(String url, Map<String, String> params, DataCallBack callBack) {
        getInstance().inner_postJsonAsync(url, params, callBack);
    }
    //-------------对外提供的方法End--------------------------------

    /**
     * 异步get请求(Form),内部实现方法
     *
     * @param url    url
     * @param params key value
     */
    private void inner_getFormAsync(String url, Map<String, String> params, final DataCallBack callBack) {
        if (params == null) {
            params = new HashMap<>();
        }
        // 请求url(baseUrl+参数)
        final String doUrl = urlJoint(url, params);
        // 新建一个请求
        final Request request = new Request.Builder().url(doUrl).build();
        //执行请求获得响应结果
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                deliverDataFailure(request, e, callBack);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) { // 请求成功
                    //执行请求成功的操作
                    String result = response.body().string();
                    deliverDataSuccess(result, callBack);
                } else {
                    throw new IOException(response + "");
                }
            }
        });
    }

    /**
     * 异步post请求(Form),内部实现方法
     *
     * @param url      url
     * @param params   params
     * @param callBack callBack
     */
    private void inner_postFormAsync(String url, Map<String, String> params, final DataCallBack callBack) {
        RequestBody requestBody;
        if (params == null) {
            params = new HashMap<>();
        }
        FormBody.Builder builder = new FormBody.Builder();
        /**
         * 在这对添加的参数进行遍历
         */
        for (Map.Entry<String, String> map : params.entrySet()) {
            String key = map.getKey();
            String value;
            /**
             * 判断值是否是空的
             */
            if (map.getValue() == null) {
                value = "";
            } else {
                value = map.getValue();
            }
            /**
             * 把key和value添加到formbody中
             */
            builder.add(key, value);
        }
        requestBody = builder.build();
        //结果返回
        final Request request = new Request.Builder().url(url).post(requestBody).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                deliverDataFailure(request, e, callBack);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) { // 请求成功
                    //执行请求成功的操作
                    String result = response.body().string();
                    deliverDataSuccess(result, callBack);
                } else {
                    throw new IOException(response + "");
                }
            }
        });
    }

    /**
     * post请求传json
     *
     * @param url      url
     * @param callBack 成功或失败回调
     * @param params   params
     */
    private void inner_postJsonAsync(String url, Map<String, String> params, final DataCallBack callBack) {
        // 将map转换成json,需要引入Gson包
        String mapToJson = new Gson().toJson(params);
        final Request request = buildJsonPostRequest(url, mapToJson);
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                deliverDataFailure(request, e, callBack);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) { // 请求成功
                    //执行请求成功的操作
                    String result = response.body().string();
                    deliverDataSuccess(result, callBack);
                } else {
                    throw new IOException(response + "");
                }
            }
        });
    }

    /**
     * Json_POST请求参数
     *
     * @param url  url
     * @param json json
     * @return requestBody
     */
    private Request buildJsonPostRequest(String url, String json) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json);
        return new Request.Builder().url(url).post(requestBody).build();
    }

    /**
     * 分发失败的时候调用
     *
     * @param request  request
     * @param e        e
     * @param callBack callBack
     */
    private void deliverDataFailure(final Request request, final IOException e, final DataCallBack callBack) {
        /**
         * 在这里使用异步处理
         */
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.requestFailure(request, e);
                }
            }
        });
    }

    /**
     * 分发成功的时候调用
     *
     * @param result   result
     * @param callBack callBack
     */
    private void deliverDataSuccess(final String result, final DataCallBack callBack) {
        /**
         * 在这里使用异步线程处理
         */
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    try {
                        callBack.requestSuccess(result);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    /**
     * 数据回调接口
     */
    public interface DataCallBack {

        void requestSuccess(String result) throws Exception;

        void requestFailure(Request request, IOException e);
    }

    /**
     * 拼接url和请求参数
     *
     * @param url    url
     * @param params key value
     * @return String url
     */
    private static String urlJoint(String url, Map<String, String> params) {
        StringBuilder endUrl = new StringBuilder(url);
        boolean isFirst = true;
        Set<Map.Entry<String, String>> entrySet = params.entrySet();
        for (Map.Entry<String, String> entry : entrySet) {
            if (isFirst && !url.contains("?")) {
                isFirst = false;
                endUrl.append("?");
            } else {
                endUrl.append("&");
            }
            endUrl.append(entry.getKey());
            endUrl.append("=");
            endUrl.append(entry.getValue());
        }
        return endUrl.toString();
    }
}

2.使用

	String url = "网络请求地址“;
	HashMap<String,String> params = new HashMap<>();
	params.put("key","value");
	  // ...
        NetRequest.getFormRequest(url, params, new NetRequest.DataCallBack() {
            @Override
            public void requestSuccess(String result) throws Exception {
                // 请求成功的回调
            }

            @Override
            public void requestFailure(Request request, IOException e) {
                // 请求失败的回调
            }
        });
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值