无所不能的拦截器

开发中有没有遇到类似的情况:
1,服务器大佬在数据请求成功的时候返回的数据和请求失败的时候返回的数据不一致,并且无法有效沟通,他甚至想打你,如下:
这是成功的数据

{
    "code":200,
    "msg":"OK",
    "data":{}
}

这是失败的数据

{
    "code":201,
    "msg":"OK",
    "data":[]
}

2,服务器大佬要求所有的参数进行md5加密,当然可以写个工具类对每个接口都进行加密,但是如果有一天不加密了呢,那就要该很多地方,写法很low啊.
....
还有很多用到的情况,就不多说,下面看着俩种情况怎们处理

一,处理数据结构不一致问题

首先就看上面的简单的数据结构,一般情况我们都会对接口请求返回的数据结构进行封装,如上的data我们请求成功的时候用拿到的是一个大括号(对象),而请求出错的时候我们拿到的是一个中括号(对象集合),这样我们封装的就冲突了,下面是处理办法:

 @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        if (response.code() == 200) {
            ResponseBody body = response.body();
            BufferedSource source = body.source();
            source.request(Long.MAX_VALUE); // Buffer the entire body.
            Buffer buffer = source.buffer();
            String string = buffer.clone().readString(Charset.forName("UTF-8"));
            try {
                JSONObject jsonObject = new JSONObject(string);
                int code = jsonObject.getInt("code");
                if (code == ErroCode.OVERPAY) {
                    Response response2 = toOverpay(jsonObject, response);
                    return response2;
                } else if (code == ErroCode.FAIL) {
---------------------------------------------------------------------------------------
                    jsonObject.put("data", new Object());
-------------------------------------------------------------------------------------------
                    String string1 = jsonObject.toString();
                    Buffer buffer1 = response.body().source().buffer();
                    buffer1.clear();
                    buffer1.writeString(string1, Charset.forName("UTF-8"));
                }
                return response;
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return response;
        }

        return response;
    }

其他的地方不用管了,那是一些其他的相关逻辑,如果只处理上面那俩个简单的数据结构,看虚线中间的哪一行就可以了,就是这么简单.

二,参数加密
加密有很多加密的算法,只拿我某个项目中的md5来举个例子吧,直接看代码

public class Md5Interceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = null;
        String method = request.method();
        switch (method) {
            case "POST":
                response = postMd5(chain, request);
                break;

            case "GET":
                response = getMd5(chain, request);
                break;
        }
        return response;


    }

    /**
     * get请求url参数加密
     *
     * @param chain
     * @param request
     * @return
     */
    private Response getMd5(Chain chain, Request request) throws IOException {
        Response response;//url
        String actionUrl = null;
        HttpUrl url = request.url();
        Set<String> set = url.queryParameterNames();
        Map<String, String> map = new HashMap<>();
        for (String name : set) {
            if (name.equals("service")) {
                actionUrl =url.queryParameter(name);
            }
            else if (!name.equals("s")) {
                map.put(name, url.queryParameter(name));
            }
        }
        StringBuilder tempParams = new StringBuilder();
        int pos = 0;
        for (String key : map.keySet()) {
            if (pos > 0) {
                tempParams.append("&");
            }
            tempParams.append(String.format("%s=%s", key, URLEncoder.encode(map.get(key), "utf-8")));
            pos++;
        }
        final String requestUrl = String.format("%s%s&%s", Api.baseUrl, actionUrl, tempParams.toString()) + Md5Utils.md5Encryption(actionUrl, map);
        final Request request1 = new Request.Builder().url(requestUrl).build();
        response = chain.proceed(request1);
        return response;

    }

    /**
     * post请求url参数加密
     *
     * @param chain
     * @param request
     * @return
     * @throws IOException
     */
    private Response postMd5(Chain chain, Request request) throws IOException {
        Response response;//url
        String actionUrl = null;
        FormBody body = (FormBody) request.body();
        FormBody.Builder builder = new FormBody.Builder();
        Map<String, String> map = new HashMap<>();
        for (int i = 0; i < body.size(); i++) {
            if (body.name(i).equals("service")) {
                actionUrl = body.value(i);
            } else {
                builder.add(body.name(i), body.value(i));
                map.put(body.name(i), body.value(i));
            }
        }
        RequestBody formBody = builder.build();
        final String requestUrl = String.format("%s%s", Api.baseUrl, actionUrl) + Md5Utils.md5Encryption(actionUrl, map);
        final Request request1 = new Request.Builder().url(requestUrl).post(formBody).build();
        response = chain.proceed(request1);
        return response;
    }
}

这个是某个简单的拦截器,就是根据get 或者 post 把每个参数取出来进行加密,然后再重新放到response中,加密规则就不说了,每个项目都不一样.只需注意一下怎们取参数即可.
所以说拦截器是个很牛x的机制,凡是涉及到网络层面的东西,大部分可以用拦截器去解决,如果有道了什么接口请求方面的问题,不妨想想拦截器.

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 11,172评论 6 13
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,613评论 8 265
  • 正确认识价值观 不想寄篱人下苟且的生活。首先,要摆正生活态度遇到事情要有自己的判断,而不是人云亦云没有观点,遇事随...
    念追忆loveing阅读 607评论 0 1
  • 马上到十二月了,没什么感觉,南方比北方的好就在于让我感受不到秋风萧瑟、叶落树枯的凄凉景象。也有可能是工作了,每天都...
    郭伦良阅读 325评论 3 0
  • 外观模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。 ...
    涵仔睡觉阅读 1,256评论 0 0