每天記錄學習的新知識 :OKHTTP 過一遍請求

參考和轉載地址:

參考文章地址:OkHttp基礎概念解釋
轉載文章地址:Okhttp3基本使用
官方地址 https://github.com/square/okhttp

簡介OKHTTP

square公司出品,OkHttp官網GitHub地址

1. 優勢

  1. 支持HTTP2/SPDY,如果SPDY不可用,則通過連接池來減少請求延時

  2. socket自動選擇最好路線,並支持自動重連,擁有自動維護的socket連接池,減少握手次數,減少了請求延遲,共享Socket,減少對服務器的請求次數

  3. 基於Headers的緩存策略減少重複的網絡請求

  4. 擁有Interceptors輕鬆處理請求與響應(自動處理GZip壓縮),減少了下載大小

  5. 當網絡出現問題時,OkHttp 會自動重試一個主機的多個 IP 地址

  6. 使用簡單,支持同步阻塞調用和帶回調的異步調用

2. 使用

2.1 添加依賴和權限

最新版本,可以進入官網查看。

    implementation 'com.squareup.okhttp3:okhttp:3.13.1'
<uses-permission android:name="android.permission.INTERNET" />

2.2 Get同步請求:

Response response = call.execute();

2.3 Get異步請求

                String url = "http://wwww.baidu.com";
                OkHttpClient okHttpClient = new OkHttpClient();
                final Request request = new Request.Builder()
                        .url(url)
                        .get()//默認就是GET請求,可以不寫
                        .build();
                Call call = okHttpClient.newCall(request);
                call.enqueue(new Callback() {
                    @Override
                    public void onFailure(@NonNull Call call, IOException e) {
                        LogUtils.e(TAG, "onFailure: ");
                    }

                    @Override
                    public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {

                        String content = response.body().string();
                        LogUtils.i(TAG, "onResponse: " + content);
                    }
                });

注:response.body().string(); 只能調用一次,再次調用不會再有返回結果,所以需要緩存一下。

2.4 Post請求,請求參數爲String

post 請求需要構建RequestBody,並且RequestBody需要指定MediaType。

String 對應的

MediaType.parse("application/json; charset=utf-8")
                String encodedPwd = "";
                final Base64.Encoder encoder;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    encoder = Base64.getEncoder();

                    final String text = MD5Utils.md5("123qwe");
                    byte[] textByte = new byte[0];
                    try {
                        textByte = text.getBytes("UTF-8");
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }

                    encodedPwd = encoder.encodeToString(textByte);
                    System.out.println("編碼 encodedText ==" + encodedPwd);
                }

                Map<String, String> body = new HashMap<>();
                body.put("phone", "15612345678");
                body.put("password", encodedPwd);

                RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), new Gson().toJson(body));

                Request request1 = new Request.Builder()
                        .addHeader("time", String.valueOf(System.currentTimeMillis()))
                        .addHeader("requestId", UUID.randomUUID().toString().replace("-", ""))
                        .addHeader("Content-Type", "application/json")
                        .addHeader("charset", "UTF-8")
                        .addHeader("Accept", "application/json")
                        .url(baseUrl + DOMAIN1 + LOGIN)
                        .post(requestBody)
                        .build();

                OkHttpClient okHttpClient1 = new OkHttpClient();
                okHttpClient1.newCall(request1).enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        Log.d(TAG, "onFailure: " + e.getMessage());
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
                        Headers headers = response.headers();
                        for (int i = 0; i < headers.size(); i++) {
                            Log.d(TAG, headers.name(i) + ":" + headers.value(i));
                        }
                        Log.d(TAG, "onResponse: " + response.body().string());
                    }
                });

Retrofit請求API:

    @POST(DOMAIN1 +LOGIN)
    Observable<ResponseNull> login(@Body Map<String, String> body);

上面代碼中的body可以直接用在這裏,因爲類型一致所以並不需要轉換類型,也可以自定義。

注意:Bad request 可能是因爲類型轉換錯誤導致。

2.5 Post請求,參數爲流

RequestBody requestBody = new RequestBody() {
    @Nullable
    @Override
    public MediaType contentType() {
        return MediaType.parse("text/x-markdown; charset=utf-8");
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        sink.writeUtf8("I am Jdqm.");
    }
};

2.6 Post請求,參數爲文件

                File file2 = new File(picturePath);
                RequestBody photo = RequestBody.create(MediaType.parse("multipart/form-data"), file2);

Retrofit請求API:

2.6 Post請求,參數爲表單

RequestBody requestBody = new FormBody.Builder()
        .add("search", "Jurassic Park")
        .build();

2.6 Post請求,多參數請求

    MultipartBody body = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addPart(
                    Headers.of("Content-Disposition", "form-data; name=\"title\""),
                    RequestBody.create(null, "Square Logo"))
            .addPart(
                    Headers.of("Content-Disposition", "form-data; name=\"image\""),
                    RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
            .build();

2.6.1 普通鍵值對

            .addPart(
                    Headers.of("Content-Disposition", "form-data; name=\"title\""),
                    RequestBody.create(null, "Square Logo"))

2.6.2 文件的傳輸

            .addPart(
                    Headers.of("Content-Disposition", "form-data; name=\"image\""),
                    RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))

以上是文件的傳輸。

2.6.1.1 MEDIA_TYPE_PNG
  1. MediaType.parse(“image/png”)
  2. MediaType.parse(“image/*”)
  3. MediaType.parse(“image/jpg”)
2.6.1.2 文件名稱
             Headers.of("Content-Disposition", "form-data; name=\"file\";filename=\"file.jpg\""),
             RequestBody.create(MediaType.parse("image/png"), file3))
2.6.1.3 addFormDataPart

這個方法是OKHTTP對於addPart的封裝

	.addFormDataPart("file", file3.getName(), RequestBody.create(MediaType.parse("image/*"), file3))

2.6.3 retrofit 多參數

    @Multipart
    @POST(DOMAIN2 + "/c/file/update")
    Observable<Response> updatePic(@PartMap Map<String, RequestBody> params);

@Multipart:

Multipart = MultipartBody.FORM = MediaType.parse("multipart/form-data")

multipart/form-data:
指定傳輸數據爲二進制數據,例如圖片、mp3、文件;
它會將表單的數據處理爲一條消息,以標籤爲單元,用分隔符分開。既可以上傳鍵值對,也可以上傳文件。當上傳的字段是文件時,會有Content-Type來表名文件類型;content-disposition,用來說明字段的一些信息;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章