okhttp3 synchronous request usage summary

Official documentation: https://github.com/square/okhttp/wiki/Recipes

https://github.com/square/okhttp

 

The following only considers requests with small data volume, such as requesting rest json API

 

 

Relevant points of attention

1. The builder mode is used in many places in okhttp3. OkHttpClient, Request, FormBody, etc. can obtain the corresponding Builder through <Class>.Builder(), and then perform related configuration.

 

2. When the ResponseBody is used up, it should be closed in time

Each response body is backed by a limited resource like a socket (live network responses) or an open file (for cached responses). Failing to close the response body will leak these resources and may ultimately cause the application to slow down or crash. Close the response body by calling either close()byteStream().close(), or reader().close(). The bytes() and string() methods both close the response body automatically.

 

 

Related Request Code

First create a custom Response (this personal preference)

public static class Response {
    public Integer code;
    public String content;
}

 

 

Get request

/**
 * http get request
 * @param url request uri
 * @return Response request result instance, judge whether it is valid by response.code==200
 */
public static Response httpGet(String url) {

    Response response = new Response();

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
            .url(url)
            .build();

    proceedRequest(client, request, response);

    return response;
}

 

 

Generic handling request function here

private static void proceedRequest(OkHttpClient client, Request request, Response response) {
    try {
        okhttp3.Response temp = client.newCall(request).execute();
        response.code = temp.code();
        ResponseBody body = temp.body();
        if (temp.isSuccessful()) {
            //call string auto close body
            response.content = body.string();
        } else {
            response.content = "Network request failed";
            temp.body().close();
        }
    } catch (IOException e) {
        e.printStackTrace ();
        Log.w(TAG, e.getMessage() == null ? " " : e.getMessage());
        response.code = -1;
        response.content = e.getMessage();
    }
}

 

 

Post Json string request

/**
 * http post request
 * @param url request url
 * @param jsonStr post parameter
 * @return Response request result instance, judged by response.code==200
 */
public static Response httpPost(String url, String jsonStr) {
    Response response = new Response();

    MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    OkHttpClient client = new OkHttpClient();

    RequestBody body = RequestBody.create(JSON, jsonStr);
    Request request = new Request.Builder()
            .url(url)
            .post(body)
            .build();

    proceedRequest(client, request, response);

    return response;
}

 

 

Post Form request

/**
 * http post request
 * @param url request url
 * @param para post parameter, form key-value pair
 * @return HttpResponse request result instance
 */
public static Response httpPostForm(String url, Map<String, String> para) {
    if (para == null || para.size() == 0)
        return null;

    Response response = new Response();

    OkHttpClient client = new OkHttpClient();

    FormBody.Builder builder = new FormBody.Builder();

    for (Map.Entry<String, String> entry : para.entrySet()) {
        builder.add(entry.getKey(), entry.getValue());
    }

    RequestBody formBody = builder.build();

    Request request = new Request.Builder()
            .url(url)
            .post(formBody)
            .build();

    proceedRequest(client, request, response);

    return response;
}

 

 

Put Json String Request

very similar to post

/**
 * http put request
 * @param url request url
 * @param jsonStr post parameter
 * @return Response request result instance, judged by response.code==200
 */
public static Response httpPut(String url, String jsonStr) {
    Response response = new Response();

    MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    OkHttpClient client = new OkHttpClient();

    RequestBody body = RequestBody.create(JSON, jsonStr);
    Request request = new Request.Builder()
            .url(url)
            .put(body)
            .build();

    proceedRequest(client, request, response);

    return response;
}

 

 

If the Request needs to carry custom header information

Request request = new Request.Builder()
        .url(getPayPalAccessTokenUrl())
        .header("Accept", "application/json")
        .header("Content-Type", "application/x-www-form-urlencoded")
        .header("Authorization", "some secret token")
        .post(body)
        .build();

 

 

If you need to add custom SSL rules

1) Custom SSL classes, such as forcing the use of the TLSv1.2 protocol

/**
 * XZTLSSocketFactory.java
 *
 * Created by xuanzhui on 2016/3/18.
 * Copyright (c) 2016 xuanzhui. All rights reserved.
 */
package cn.beecloud;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class XZTLSSocketFactory extends SSLSocketFactory {

    private SSLSocketFactory delegate;

    public XZTLSSocketFactory() throws KeyManagementException, NoSuchAlgorithmException {
        SSLContext context = SSLContext.getInstance("TLSv1.2");
        context.init(null, null, null);
        delegate = context.getSocketFactory();
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return delegate.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return delegate.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return enableTLSOnSocket(delegate.createSocket(s, host, port, autoClose));
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException {
        return enableTLSOnSocket(delegate.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return enableTLSOnSocket(delegate.createSocket(host, port, localHost, localPort));
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return enableTLSOnSocket(delegate.createSocket(host, port));
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return enableTLSOnSocket(delegate.createSocket(address, port, localAddress, localPort));
    }

    private Socket enableTLSOnSocket(Socket socket) {
        if(socket != null && (socket instanceof SSLSocket)) {
            ((SSLSocket)socket).setEnabledProtocols(new String[] {"TLSv1.2"});
        }
        return socket;
    }
}

 

2) Set up OkHttpClient

OkHttpClient client = new OkHttpClient.Builder()
						//Define the connection timeout
                    	.connectTimeout(connectTimeout, TimeUnit.MILLISECONDS)
                    	//Custom SSL protocol
                    	.sslSocketFactory(new XZTLSSocketFactory()).build();

 

About the support list of android SSL protocol

Client socket:

Protocol Supported (API Levels) Enabled by default (API Levels)
SSLv3 1+ 1+
TLSv1 1+ 1+
TLSv1.1 16+ 20+
TLSv1.2 16+ 20+


Server socket:

Protocol Supported (API Levels) Enabled by default (API Levels)
SSLv3 1+ 1+
TLSv1 1+ 1+
TLSv1.1 16+ 16+
TLSv1.2 16+ 16+

Means API level 16+ (Android 4.1, Jelly Bean) is the minimum version requirement to support TLSv1.2

ref Android 4.1+ enable TLS 1.1 and TLS 1.2

 

If you encounter an error

java.lang.IllegalStateException: Unable to extract the trust manager on okhttp3.internal.Platform

Rename the member variable SSLSocketFactory to delegate

ref https://github.com/square/okhttp/issues/2323

 

 

 

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326976039&siteId=291194637