成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Retrofit2.0 公共參數(shù)(固定參數(shù))

Ashin / 2715人閱讀

摘要:封裝公共參數(shù)和密碼添加新的參數(shù)新的請(qǐng)求使用了裝飾者模式使用添加。使用模式,暴露以下接口請(qǐng)求,且為時(shí),鍵值對(duì)公共參數(shù)插入到參數(shù)中,其他情況插入到參數(shù)中。通過構(gòu)建要上傳的一些基本公共的參數(shù),然后通過符號(hào)在的里面其他要提交參數(shù)拼接。

請(qǐng)先閱讀:
Retrofit 動(dòng)態(tài)參數(shù)(非固定參數(shù)、非必須參數(shù))(Get、Post請(qǐng)求)

在實(shí)際項(xiàng)目中,對(duì)于有需要統(tǒng)一進(jìn)行公共參數(shù)添加的網(wǎng)絡(luò)請(qǐng)求,可以使用下面的代碼來實(shí)現(xiàn):

RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(ctx).setRequestInterceptor(new RequestInterceptor() {
                    @Override
                    public void intercept(RequestFacade request) {
                        request.addQueryParam("publicParams", "1");
                    }
                }).setConverter(new BaseConverter())
                .build();

在RestAdapter的實(shí)例化對(duì)象的時(shí)候,為其指定一個(gè)RequestInterceptor接口的實(shí)現(xiàn)類即可,在該類中,可以對(duì)請(qǐng)求體的相關(guān)參數(shù)進(jìn)行設(shè)置,如addHeader、addQueryParam等。

不過遺憾的是Retrofit2.0已經(jīng)沒有了該類,該怎么做呢?通過Interceptor實(shí)現(xiàn)。

Interceptor是攔截器, 在發(fā)送之前, 添加一些參數(shù), 或者獲取一些信息。

/**
 * 封裝公共參數(shù)(Key和密碼)
 * 

*/ public class CommonInterceptor implements Interceptor { private final String mApiKey; private final String mApiSecret; public CommonInterceptor(String apiKey, String apiSecret) { mApiKey = apiKey; mApiSecret = apiSecret; } @Override public Response intercept(Interceptor.Chain chain) throws IOException { String marvelHash = ApiUtils.generateMarvelHash(mApiKey, mApiSecret); Request oldRequest = chain.request(); // 添加新的參數(shù) HttpUrl.Builder authorizedUrlBuilder = oldRequest.url() .newBuilder() .scheme(oldRequest.url().scheme()) .host(oldRequest.url().host()) .addQueryParameter(MarvelService.PARAM_API_KEY, mApiKey) .addQueryParameter(MarvelService.PARAM_TIMESTAMP, ApiUtils.getUnixTimeStamp()) .addQueryParameter(MarvelService.PARAM_HASH, marvelHash); // 新的請(qǐng)求 Request newRequest = oldRequest.newBuilder() .method(oldRequest.method(), oldRequest.body()) .url(authorizedUrlBuilder.build()) .build(); return chain.proceed(newRequest); } }

Okhttp3使用了裝飾者模式, 使用Builder添加Interceptor。

CommonInterceptor commonInterceptor = new CommonInterceptor(
                "key", "Secret");

OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(commonInterceptor)
                .build();

// 適配器
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("url")             
        .addConverterFactory(GsonConverterFactory.create()
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .client(client)
        .build();

有時(shí)候你找到了一條線,就能順著線找到更多。

BasicParamsInterceptor - 為 OkHttp 請(qǐng)求添加公共參數(shù)

背景

在 Android Http API 請(qǐng)求開發(fā)中經(jīng)常遇到這樣的需求:每一次請(qǐng)求帶上一個(gè)或者多個(gè)固定不變的參數(shù),例如:

設(shè)備唯一標(biāo)識(shí):device_id = 7a4391e28f309c21

業(yè)務(wù)唯一標(biāo)識(shí):uid = 2231001

平臺(tái)類型:platform = android

客戶端版本號(hào):version_code = 6

這些參數(shù)是每一次發(fā)生請(qǐng)求都需要的,我們姑且稱他們?yōu)楣矃?shù)(或者基礎(chǔ)參數(shù))。公共參數(shù)一般以 header line、url query 或者 post body(較少) 這些形式插入請(qǐng)求。

實(shí)現(xiàn)

如果使用 OkHttp 作為 http request client, 這件事情就變得簡(jiǎn)單多了。OkHttp 提供了強(qiáng)大的攔截器組件 (Interceptor):

Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls.

也就是說,OkHttp 的攔截器功能之一就是對(duì)將要發(fā)出的請(qǐng)求進(jìn)行攔截、改造然后再發(fā)出。這正是我們想要的。BasicParamsInterceptor 實(shí)現(xiàn)了 okhttp3.Interceptor 接口。

實(shí)現(xiàn) public Response intercept(Chain chain) throws IOException 方法。使用 Builder 模式,暴露以下接口:

addParam(String key, String value)

post 請(qǐng)求,且 body type 為 x-www-form-urlencoded 時(shí),鍵值對(duì)公共參數(shù)插入到 body 參數(shù)中,其他情況插入到 url query 參數(shù)中。

addParamsMap(Map paramsMap)

同上,不過這里用鍵值對(duì) Map 作為參數(shù)批量插入。

addHeaderParam(String key, String value)

在 header 中插入鍵值對(duì)參數(shù)。

addHeaderParamsMap(Map headerParamsMap)

在 header 中插入鍵值對(duì) Map 集合,批量插入。

addHeaderLine(String headerLine)

在 header 中插入 headerLine 字符串,字符串需要符合 -1 != headerLine.indexOf(“:”) 的規(guī)則,即可以解析成鍵值對(duì)。

addHeaderLinesList(List headerLinesList)

同上,headerLineList: List 為參數(shù),批量插入 headerLine。

addQueryParam(String key, String value)

插入鍵值對(duì)參數(shù)到 url query 中。

addQueryParamsMap(Map queryParamsMap)

插入鍵值對(duì)參數(shù) map 到 url query 中,批量插入。

示例

使用 Buider 模式創(chuàng)建 Interceptor 對(duì)象,然后調(diào)用 OkHttp 的 addInterceptor(Interceptor i) 方法將 interceptor 對(duì)象添加至 client 中:

BasicParamsInterceptor basicParamsInterceptor =
        new OkPublicParamsInterceptor.Builder()
                .addHeaderParam("device_id", DeviceUtils.getDeviceId())
                .addParam("uid", UserModel.getInstance().getUid())
                .addQueryParam("api_version", "1.1")
                .build();
OkHttpClient client = new OkHttpClient.Builder()
        .addInterceptor(basicParamsInterceptor)
        .build();

TODO

自動(dòng)時(shí)間戳公共參數(shù)的支持

動(dòng)態(tài)參數(shù)的支持(例如登錄后插入服務(wù)器返回的 uid)
源碼

源碼與引用:https://github.com/jkyeo/okht...

basicparamsinterceptor應(yīng)用

配置基本提交參數(shù)

我們可以建一個(gè)攔截器,這里我舉例加些簡(jiǎn)單的系統(tǒng)參數(shù),如下:

 class HttpBaseParamsLoggingInterceptor implements Interceptor{

        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Request.Builder requestBuilder = request.newBuilder();
            RequestBody formBody = new FormBody.Builder()
            .add("userId", "10000")
            .add("sessionToken", "E34343RDFDRGRT43RFERGFRE")
            .add("q_version", "1.1")
            .add("device_id", "android-344365")
            .add("device_os", "android")
            .add("device_osversion","6.0")
            .add("req_timestamp", System.currentTimeMillis() + "")
            .add("app_name","forums")
            .add("sign", "md5")
            .build();
            String postBodyString = Utils.bodyToString(request.body());
            postBodyString += ((postBodyString.length() > 0) ? "&" : "") +  Utils.bodyToString(formBody);
            request = requestBuilder
                    .post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"),
                            postBodyString))
                    .build();
            return chain.proceed(request);
        }
    }

上面Utils類是使用的okio.Buffer里面的工具類。通過RequestBody構(gòu)建要上傳的一些基本公共的參數(shù),然后通過”&”符號(hào)在http 的body里面其他要提交參數(shù)拼接。然后再通過requestBuilder重新創(chuàng)建request對(duì)象,然后再通過chain.proceed(request)返回Response 。

接下來在創(chuàng)建OkHttpClient對(duì)象的時(shí)候修改為如下代碼:

mOkHttpClient = new OkHttpClient.Builder()
     .addInterceptor(interceptor)
     .addInterceptor(new HttpBaseParamsLoggingInterceptor())
     .build();

這樣就添加好了一些基本的公共參數(shù)。

下面我們借助BasicParamsInterceptor實(shí)現(xiàn),代碼如下:

public class BasicParamsInterceptor implements Interceptor {

    Map queryParamsMap = new HashMap<>();
    Map paramsMap = new HashMap<>();
    Map headerParamsMap = new HashMap<>();
    List headerLinesList = new ArrayList<>();

    private BasicParamsInterceptor() {

    }

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();
        Request.Builder requestBuilder = request.newBuilder();

        // process header params inject
        Headers.Builder headerBuilder = request.headers().newBuilder();
        if (headerParamsMap.size() > 0) {
            Iterator iterator = headerParamsMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
            }
        }

        if (headerLinesList.size() > 0) {
            for (String line: headerLinesList) {
                headerBuilder.add(line);
            }
        }

        requestBuilder.headers(headerBuilder.build());
        // process header params end




        // process queryParams inject whatever it"s GET or POST
        if (queryParamsMap.size() > 0) {
            injectParamsIntoUrl(request, requestBuilder, queryParamsMap);
        }
        // process header params end




        // process post body inject
        if (request.method().equals("POST") && request.body().contentType().subtype().equals("x-www-form-urlencoded")) {
            FormBody.Builder formBodyBuilder = new FormBody.Builder();
            if (paramsMap.size() > 0) {
                Iterator iterator = paramsMap.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry entry = (Map.Entry) iterator.next();
                    formBodyBuilder.add((String) entry.getKey(), (String) entry.getValue());
                }
            }
            RequestBody formBody = formBodyBuilder.build();
            String postBodyString = bodyToString(request.body());
            postBodyString += ((postBodyString.length() > 0) ? "&" : "") +  bodyToString(formBody);
            requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
        } else {    // can"t inject into body, then inject into url
            injectParamsIntoUrl(request, requestBuilder, paramsMap);
        }

        request = requestBuilder.build();
        return chain.proceed(request);
    }

    // func to inject params into url
    private void injectParamsIntoUrl(Request request, Request.Builder requestBuilder, Map paramsMap) {
        HttpUrl.Builder httpUrlBuilder = request.url().newBuilder();
        if (paramsMap.size() > 0) {
            Iterator iterator = paramsMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                httpUrlBuilder.addQueryParameter((String) entry.getKey(), (String) entry.getValue());
            }
        }

        requestBuilder.url(httpUrlBuilder.build());
    }

    private static String bodyToString(final RequestBody request){
        try {
            final RequestBody copy = request;
            final Buffer buffer = new Buffer();
            if(copy != null)
                copy.writeTo(buffer);
            else
                return "";
            return buffer.readUtf8();
        }
        catch (final IOException e) {
            return "did not work";
        }
    }

    public static class Builder {

        BasicParamsInterceptor interceptor;

        public Builder() {
            interceptor = new BasicParamsInterceptor();
        }

        public Builder addParam(String key, String value) {
            interceptor.paramsMap.put(key, value);
            return this;
        }

        public Builder addParamsMap(Map paramsMap) {
            interceptor.paramsMap.putAll(paramsMap);
            return this;
        }

        public Builder addHeaderParam(String key, String value) {
            interceptor.headerParamsMap.put(key, value);
            return this;
        }

        public Builder addHeaderParamsMap(Map headerParamsMap) {
            interceptor.headerParamsMap.putAll(headerParamsMap);
            return this;
        }

        public Builder addHeaderLine(String headerLine) {
            int index = headerLine.indexOf(":");
            if (index == -1) {
                throw new IllegalArgumentException("Unexpected header: " + headerLine);
            }
            interceptor.headerLinesList.add(headerLine);
            return this;
        }

        public Builder addHeaderLinesList(List headerLinesList) {
            for (String headerLine: headerLinesList) {
                int index = headerLine.indexOf(":");
                if (index == -1) {
                    throw new IllegalArgumentException("Unexpected header: " + headerLine);
                }
                interceptor.headerLinesList.add(headerLine);
            }
            return this;
        }

        public Builder addQueryParam(String key, String value) {
            interceptor.queryParamsMap.put(key, value);
            return this;
        }

        public Builder addQueryParamsMap(Map queryParamsMap) {
            interceptor.queryParamsMap.putAll(queryParamsMap);
            return this;
        }

        public BasicParamsInterceptor build() {
            return interceptor;
        }

    }
}

只要像上面一樣配置就行了。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/65011.html

相關(guān)文章

  • node結(jié)合swig渲染摸板實(shí)現(xiàn)前后端不分離

    在這里就nodejs如何應(yīng)用swig摸板,總結(jié)一下一些基本的用法。首先當(dāng)然是利用express框架在node后臺(tái)上面搭建服務(wù) var express = require(express); var server = express(); server.listen(8080,localhost,(req,res)=>{ console.log(服務(wù)器啟動(dòng)...); }) 啟動(dòng)成功之后,...

    jeffrey_up 評(píng)論0 收藏0
  • Solidity 簡(jiǎn)易教程

    摘要:語句以分號(hào)結(jié)尾狀態(tài)變量狀態(tài)變量是被永久地保存在合約中。中,實(shí)際上是代名詞,一個(gè)位的無符號(hào)整數(shù)。下面的語句被認(rèn)為是修改狀態(tài)修改狀態(tài)變量。事件事件是合約和區(qū)塊鏈通訊的一種機(jī)制。一旦它被發(fā)出,監(jiān)聽該事件的都將收到通知。 Solidity是以太坊的主要編程語言,它是一種靜態(tài)類型的 JavaScript-esque 語言,是面向合約的、為實(shí)現(xiàn)智能合約而創(chuàng)建的高級(jí)編程語言,設(shè)計(jì)的目的是能在以太坊虛...

    chenatu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<