1. Introduction

Okhttp3 is an underlying network framework that is basically in use today. The main purpose of this blog post is to document where the OKHttp3 framework can be used in development, as well as when a tool document is easy to find for later use.

If you already know how to do it, check out this article to learn all about OKHttp3.

2. Environment construction

First remember to add dependencies and network permissions to build.gradle and configuration files, respectively

    implementation 'com. Squareup. Okhttp3: okhttp: 3.8.0'
    implementation 'com. Squareup. Okio: okio: 1.12.0'
Copy the code

And permissions

    <uses-permission android:name="android.permission.INTERNET"/>
Copy the code

And that’s it. Let’s use it

3. Get use

 OkHttpClient mClient = new OkHttpClient.Builder() // Builder pattern, create instance
                .connectTimeout(20, TimeUnit.SECONDS) // Set connection timeout
                .build();
             
        Request mRequest = new Request.Builder() // Builder pattern to create request information
                .get()
                .url("https://www.baidu.com")
                .build();

        Call call = mClient.newCall(mRequest); // Convert request to call

        call.enqueue(new Callback() { / / call execution

            @Override
            public void onFailure(Call call, IOException e) {}@Override
            public void onResponse(Call call, Response response) throws IOException {

                final String strByNet = response.body().string();

                // Switch to main thread
                runOnUiThread(new Runnable() {

                    @Override
                    public void run(a) { tv_msg.setText(strByNet); }}); }});Copy the code

Ok, so that’s a simple use of GET, but as a tool, it’s natural to list the extension properties that extend okHttpClient.Builder

 * final Dispatcher dispatcher;  // Important: dispatcher that distributes and closes calls made up of Request
 * final Proxy proxy;  / / agent
 * final List<Protocol> protocols; / / agreement
 * final List<ConnectionSpec> connectionSpecs; // Transport layer version and connection protocol
 * final List<Interceptor> interceptors; // Important: interceptor
 * final List<Interceptor> networkInterceptors; // Network interceptor
 * final ProxySelector proxySelector; // Proxy selection
 * final CookieJar cookieJar; //cookie
 * final Cache cache; / / cache
 * final InternalCache internalCache;  // Internal cache
 * final SocketFactory socketFactory;  / / socket factory
 * final SSLSocketFactory sslSocketFactory; // Socket factory for HTTPS
 * final CertificateChainCleaner certificateChainCleaner; // Verify that the response certificate applies to the host name of the HTTPS request connection.
 * final HostnameVerifier hostnameVerifier;    // Confirm the host name
 * final CertificatePinner certificatePinner;  / / certificate chain
 * final Authenticator proxyAuthenticator;     // Proxy authentication
 * final Authenticator authenticator;      // Local authentication
 * final ConnectionPool connectionPool;    // Connection pool, multiplexing connections
 * final Dns dns;  / / domain name
 * final boolean followSslRedirects;  // SSL redirection
 * final boolean followRedirects;  // Local redirect
 * final boolean retryOnConnectionFailure; // Retry connection failed
 * final int connectTimeout;    // Connection timed out
 * final int readTimeout; / / read timeout
 * final int writeTimeout; / / write timeout
Copy the code


4. Set up the server

To test the following functionality, we built our own server. First set up the environment, configure tomcat author is a MAC, so introduce the way to configure Tomcat under the MAC, Windows partners can refer to this (www.cnblogs.com/beginner-bo…)

  1. Download Tomcat

  1. Download file decompress

  1. Open the terminal input command, simple way, terminal input CD, and then directly drag the bin folder directly to the terminal

  2. cd /Library/Tomcat/bin

  3. The target file authorization, terminal input command

    chmod +x *.sh

  4. Start tomcat

    ./startup.sh

  5. Enter http://localhost:8080/ in the browser

Congratulations on your Tomcat configuration

Server, the authors use the IDEA how to configure Tomcat on the inside and the back to use servlets can see this article, with the friend can skip (www.cnblogs.com/wfhking/p/9)…

Well, here, the server has been built, next, we write the server program!


5. Post use

The service side

@WebServlet(name = "TestPost")
public class TestPost extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        response.setHeader("Access-Control-Allow-Origin"."*"); / / across domains
        response.setContentType("text/html"); // Set the response content type
        response.setCharacterEncoding("UTF-8"); // Specify the encoding

        // Get the data from the front end
        BufferedReader br = request.getReader();
        String line;
        StringBuffer mStringBuff = new StringBuffer();
        while((line = br.readLine()) ! =null){

            mStringBuff.append(line);
        }
        // Set the logical implementation
        PrintWriter out = response.getWriter();
        String jsonStr = "The server receives the message and returns: \n" + mStringBuff.toString();
        out.println(jsonStr);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}}Copy the code

Ok, that’s it, let’s go ahead and implement our client post

The client

  private void doPost(String username, String pass, String hobby) {

        / / code set
        final MediaType FORM_CONTENT_TYPE = MediaType.parse("application/json; charset=utf-8");

        // Interface address
        final String uri = "http://192.168.0.102:8081/TestOkhttp3_war_exploded/TestPost";

        // Create an instance
        OkHttpClient okhttp = new OkHttpClient.Builder()
                .build();

        // Create forms and data
        HashMap<String, String> map = new HashMap<>();
        map.put("username", username);
        map.put("password", pass);
        map.put("hobby", hobby);
        String jsonStr = new Gson().toJson(map);

        RequestBody formBody = RequestBody.create(FORM_CONTENT_TYPE, jsonStr);

        // Create request instance
        Request request = new Request.Builder()
                .url(uri)
                .post(formBody)
                .build();

        Call call = okhttp.newCall(request);
        call.enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("lybj"."Interface call failed");
            }

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

                final String strByNet = response.body().string();
                // Switch to main thread
                runOnUiThread(new Runnable() {

                    @Override
                    public void run(a) { tv_msg.setText(strByNet); }}); }}); }Copy the code

Of course, once you’ve done that, you get an exception

CLEARTEXT Communication ** Not permitted by Network Security Policy

There are two solutions, either using HTTPS or creating an XML folder in res and creating the file network_security_config.xml

<? The XML version = "1.0" encoding = "utf-8"? > <network-security-config> <base-config cleartextTrafficPermitted="true" /> </network-security-config>Copy the code

Reference it in the application

    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config">
Copy the code

Ok, post is ready to work

6. Post Uploads multiple files and parameters

Choose Project Settings > Artifacts > Choose your project > Artifacts > OutPut Directory on the right. Then locate the OutPut directory to view the submitted files and the parameters OutPut from the console.

The service side

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // Set the encoding
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");
        PrintWriter pw = response.getWriter();

        try {
            // Set the system environment
            DiskFileItemFactory factory = new DiskFileItemFactory();

            // File storage path
            String storePath = getServletContext().getRealPath("/WEB-INF/files");
            if(!new File(storePath).exists()){
                new File(storePath).mkdirs();
            }

            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setFileSizeMax(4 * 1024 * 1024); // Set the size of a single file to no larger than 4M
            upload.setSizeMax(4 * 1024 * 1024); // Set the total file upload size to 6 MB

            / / parsing
            List<FileItem> items = upload.parseRequest(request);
            for (FileItem item : items) {

                // The form is submitted
                if (item.isFormField()){

                    String name = item.getFieldName();
                    String value = item.getString("UTF-8");
                    System.out.println(name + "= =" + value);
                } else { // Parse the uploaded file
// String mimeType = item.getContentType(); Gets the type of the uploaded file
// if(mimeType.startsWith("image")){
                    InputStream in = item.getInputStream();
                    String fileName = item.getName();
                    if (fileName == null || "".equals(fileName.trim())) {
                        continue;
                    }
                    fileName = fileName.substring(fileName.lastIndexOf("\ \") + 1);
                    fileName = UUID.randomUUID() + "_" + fileName;

                    // Create folders by date
                    String storeFile = storePath + "/" + fileName;
                    OutputStream out = new FileOutputStream(storeFile);
                    byte[] b = new byte[1024];
                    int len = -1;
                    while((len = in.read(b)) ! = -1) {
                        out.write(b, 0, len);
                    }
                    in.close();
                    out.close();
                    item.delete(); // Delete temporary files
                }
            }
            PrintWriter out = response.getWriter();
            out.println("Upload successful");
        } catch (org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException e) {

            pw.write("A single file cannot exceed 4M");
        } catch (org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException e) {

            pw.write("Total files cannot exceed 6M.");
        } catch(FileUploadException e) { e.printStackTrace(); }}Copy the code


The client

   /** * upload file ** /
    private void doUpload(File file, String userId, String msg){

        // Interface address
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .build();

        RequestBody fileRequestBody1 = RequestBody.create(MediaTypeUtils.UPLOAD_FILE.value, file);

        // Can be multiple
        MultipartBody body = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("userId", userId)
                .addFormDataPart("msg", msg)
                .addFormDataPart("file"."myFileName", fileRequestBody1)
                .build();

        Request rb = new Request.Builder()
                .header("Authorization"."Client-ID " + UUID.randomUUID())
                .url(ApiUtils.TestPostUpload)
                .post(body)
                .build();

        Call call = client.newCall(rb);
        call.enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {

                Log.e("lybj"."Interface call failed");
            }

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

                final String string = response.body().string();
                runOnUiThread(new Runnable() {

                    @Override
                    public void run(a) { tv_msg.setText(string); }}); }}); }Copy the code

The interface is encapsulated

public interface ApiUtils {

    String BaseUri = "http://192.168.0.102:8081/TestOkhttp3_war_exploded/";

    // post submits JSON
    String TestPost = BaseUri + "TestPost";

    // Upload the file
    String TestPostUpload = BaseUri + "TestPostUpload";
}
Copy the code

Defines an enumeration type to store information for upload use

public enum MediaTypeUtils {

    JSON_UTF_8(MediaType.parse("application/json; charset=utf-8")),  // Set the Json data transfer and specify UTF-8 as the encoding set
    UPLOAD_FILE(MediaType.parse("multipart/form-data")); // Upload the file

    public MediaType value;

    MediaTypeUtils(MediaType value) {
        this.value = value; }}Copy the code

All right, that’s it

7. Post the download

To keep things simple, let’s just download APK from the web

The client

   /** * download file ** /
    private void doDownload(a){

        // Interface address
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .build();

        Request rb = new Request.Builder()
                .get()
                .url(ApiUtils.TestPostDownload)
                .build();

        Call call = client.newCall(rb);
        call.enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {

                Log.e("lybj"."Interface call failed");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException { writeFile(response); }}); }Copy the code


   /** * download file ** /
    private void writeFile(Response response) {

        InputStream is = null;
        FileOutputStream fos = null;
        is = response.body().byteStream();
        String path = Environment.getExternalStorageDirectory().getAbsolutePath();
        File file = new File(path, "hehe.apk");
        try {
            fos = new FileOutputStream(file);
            byte[] bytes = new byte[1024];
            int len = 0;
            // Get the size of the downloaded file
            long fileSize = response.body().contentLength();
            long sum = 0;
            int porSize = 0;
            while((len = is.read(bytes)) ! = -1) {
                fos.write(bytes);
                sum += len;
                porSize = (int) ((sum * 1.0 f / fileSize) * 100);
                Message message = handler.obtainMessage(1); message.arg1 = porSize; handler.sendMessage(message); }}catch (Exception e) {

            e.printStackTrace();

        } finally {
            try {
                if(is ! =null) {
                    is.close();
                }
                if(fos ! =null) { fos.close(); }}catch (IOException e) {
                e.printStackTrace();
            }
        }
        Log.i("myTag"."Download successful");
    }
Copy the code


  Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {

            if (msg.what == 1) { pro.setProgress(msg.arg1); }}};Copy the code

OK, here, download is OK, before uploading and downloading, don’t forget to apply for Android permissions dynamically.

8. Gzip compression

In order to optimize (bullshit story) the interface requires compression of uploaded data, well paste the code directly

build.gradle

   implementation 'com. Zhouyou: rxeasyhttp: 2.1.2'
Copy the code
 OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                  .addInterceptor(new GzipRequestInterceptor())
                .build();
                  
Copy the code

Of course, you need server support. OK, we’re done

9. Download source code

Client-side source code

Server-side source code