How to request a third-party interface to obtain data

Keywords: Java Android http

HTTP is a common network method for exchanging data and media in modern applications. Efficient use of HTTP can make resource loading faster and save bandwidth. OkHttpClient is an efficient HTTP client, which can generally be used to request third-party interfaces. Its request / response API is designed using constructor pattern builders and supports blocking synchronous requests and asynchronous requests with callback.

Official address   https://github.com/square/okhttp

1.1 synchronous GET request

Operation steps:

(1) Construct OkHttpClient object through new OkHttpClient();

(2) Construct the Request object;

(3) Use the OkHttpClient object and Request object constructed in the previous two steps to Call the newCall() method to construct the Call object;

(4) Submit the synchronization request through the execute() method of the Call object.

Note that the synchronous GET request will block the calling thread, so it should be executed in the sub thread in Android, otherwise it may cause ANR exceptions. After Android 3.0, the main thread is not allowed to access the network.

Code examples are as follows:

String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder().url(url)
        .get()//The default is GET request, which can be left blank
        .build();
final Call call = okHttpClient.newCall(request);
new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            Response response = call.execute();
            Log.d(TAG, "run: " + response.body().string());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

one point two   Asynchronous GET request

The request step of an asynchronous GET request is only different from the last step of a synchronous GET request. Requests initiated asynchronously will be added to the runningAsyncCalls double ended queue in the Dispatcher and executed through the thread pool without blocking the calling thread.

Operation steps:

(1) Construct OkHttpClient object through new OkHttpClient();

(2) Construct the Request object;

(3) Use the OkHttpClient object and Request object constructed in the previous two steps to Call the newCall() method to construct the Call object;

(4) The asynchronous request is submitted through the enqueue(new Callback()) method of the Call object.

Code examples are as follows:

String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
        .url(url)
        .get()//The default is GET request, which can be left blank
        .build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        Log.d(TAG, "onFailure: ");
    }

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

2.1 submitting Sting by post

The difference between this method and the previous method is that when constructing the Request object, we need to construct an additional RequestBody object to carry the data we want to submit. When constructing the RequestBody, you need to specify a MediaType to describe the content type of the Request / response body. For more information about MediaType, please see RFC 2045, several construction methods of RequstBody:


ResponseBody creat(MediaType contentType,File file)
ResponseBody creat(MediaType contentType,byte[] content)
ResponseBody creat(MediaType contentType,String content)
ResponseBody creat(MediaType contentType,ByteString content)
ResponseBody creat(MediaType contentType,byte[] content, int offset,int byteCounts)

Code example:

MediaType mediaType = MediaType.parse("text/x-markdown; charset=utf-8");
String requestBody = "I am Jdqm.";
Request request = new Request.Builder()
        .url("https://api.github.com/markdown/raw")
        .post(RequestBody.create(mediaType, requestBody))
        .build();
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.newCall(request).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());
    }
});

In addition, POST can also submit a variety of different formats, such as stream, file, form, etc. See:

OkhttpClient usage details

Here is a tool class HttpUtils for network requests:

First add maven dependencies:

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.4.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>

Network request tool class:

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

public class HttpUtils {

    private static Logger LOGGER = LoggerFactory.getLogger(HttpUtils.class);

    private static class HttpClientSingletonFactory {

        private static final OkHttpClient okHttpClientInstance = new OkHttpClient();

        public static OkHttpClient getOkHttpClientInstance() {
            return okHttpClientInstance;
        }
    }

    public static String post(String url, String json, MediaType mediaType) {
        try {
            RequestBody body = RequestBody.create(json, mediaType);
            Request request = (new Request.Builder()).url(url).post(body).build();
            return Objects.requireNonNull(HttpClientSingletonFactory.getOkHttpClientInstance().newCall(request).execute().body()).string();
        } catch (Exception e) {
            LoggerUtils.error(e, LOGGER, "HttpUtils post error, url={0}, params={1}, mediaType={2}", url, json, mediaType.toString());
            return null;
        }
    }

    public static String get(String url) {
        Request request = (new Request.Builder()).url(url).build();

        try {
            return Objects.requireNonNull(HttpClientSingletonFactory.getOkHttpClientInstance().newCall(request).execute().body()).string();
        } catch (Exception e) {
            LoggerUtils.error(e, LOGGER, "HttpUtils get error, url={0}, params={1}, mediaType={2}", url);
            return null;
        }
    }

}

Next, suppose you want to call the Gaode search service API interface to query the POI information within the range set near a longitude and latitude coordinate point. See the introduction and use documents of Gaode search service API interface for details Search POI.

Suppose you use perimeter search now, you can know from the reference document that the service address URL of the perimeter Search API is https://restapi.amap.com/v3/place/around?parameters The parameters is called the request parameter of the combination. After the URL address is constructed, the get method can be called.

Example:

//Interface address of Gaode map
private static final String AMAP_URL = "https://restapi.amap.com/";

Map<String, String> params = new HashMap<>();
params.put("keywords", request.getName());
params.put("location", request.getLongitude() + "," + request.getLatitude());
//Health care service classification reference POI classification code download https://lbs.amap.com/api/webservice/download
params.put("types", "090000");
params.put("radius", "5000");
params.put("page", "1");
params.put("offset", "20");
params.put("extensions", "all");

StringBuilder urlParams = new StringBuilder("key=ff8fe7625c889a214da630dd0e0b8c5a");
params.forEach((key, value) -> urlParams.append("&").append(key).append("=").append(value));

return HttpUtils.get(AMAP_URL + "v3/place/around" + urlParams);

Note that String data is returned at this time, but actually we can know from the document that there are a lot of JSON data. Therefore, we also need to call JSON related methods under com.alibaba.fastjson package to convert it into JSON data. For details, please refer to FastJson is responsible for the conversion between JSON format strings, JSON objects and JavaBean s,Several usages of JSON.parseObject.

Posted by Janjan on Mon, 11 Oct 2021 12:31:08 -0700