[Java] Android [HTTP communication_1] Try Web API [GET, POST]

11 minute read

Introduction

Hello. This time, let’s hit the WebAPI on Android. I will write it so that even those who hit the Web API for the first time can read it. There are various ways to hit the Web API, but use the standard Java library HttpURLConnection. There is no troublesome setting, and I think it is an orthodox method if it is used to hit the Web API.

When you hit the WebAPI, you will receive JSON as a return value, but it is difficult to format JSON on Android and output it to the screen, so while using the curl command, implement Android Yes. When using WebAPI, I think it will be much easier if you can use the curl command.

Premise

The development environment is as follows. *Android Studio 4.0.1 *TargetSdkVersion 28 *Google Nexus 5x

curl command *Ubuntu 20.04 LTS (WSL 2)

Why use Web API

If you want to make a music lyrics app or think of making a translation app. It takes time and effort to collect the lyrics data of music that increases in real time, and to collect the data and make the translation function. If you find it difficult to make your own, you will probably want to use the library. What to do if you can’t find the standard or external library? What if you want to handle data that changes in real time, such as lyrics, or if you want to use a library that does not depend on the programming language? You should look for Web API.

WebAPI has the characteristics that it is language-independent and that it is often linked to a database, so it is good at handling real-time data and huge data. Internet connection is a prerequisite for using HTTP communication, but in the case of Android, it is common to be able to always connect to the Internet, so it is no problem to create an application using WebAPI. Please note that the WebAPI cannot be temporarily used due to maintenance and the specifications are changed.

How to use Web API

If you explain it in a rigorous manner, it will be difficult to understand, so if you explain the meaning of each term in a vague way, you can roughly explain it. WebAPI refers to the part or interface in the web service that the developer is allowed to access from the program. Accessing WebAPI from a program is called a request, and returning the result of a request is called a response. To send a request, you need to specify the URL and HTTP method. HTTP methods use the most basic GET and POST. The details of how to send the request and what the response looks like are as follows.

request

URL HTTP method
http://example.com/api/get GET
http://example.com/api/post POST

response

{
    "name": "foge"
}

Thus, when you make a request, the response will be returned in the format of JSON. The GET method is mainly used to get data, and the POST method is mainly used when you want to send data including data in the request.

Which Web API to use

  • A convenient way to test HTTP communication is to use httpbin’s HP. Normally, to use WebAPI, you need to register and obtain an API key, but httpbin’s HP does not require them. You can try HTTP communication without registration. This time we will use this.
  • I will not explain in this article, but if you want to try registration and acquisition of API key as well, I think it is better to use OpenWeatherMap, which is easy to acquire API key . Getting the current weather in Tokyo is explained on various web pages, so you can try it easily.

About #httpbin Various tests can be performed by adding a fixed parameter after the URL http://httpbin.org. This time, use the following functions.

Function URL
Obtaining an IP address http://httpbin.org/ip
Test GET Request http://httpbin.org/get
POST request test http://httpbin.org/post

curl command

If you want to use curl command on Windows, install WSL2 or install curl command for Windows. WSL2 is the easiest way to use Linux environment on Windows, so it’s easy to set up. I will not touch on the installation method here. The curl command can be used for various purposes, but it is often used when making HTTP requests. Now, try hitting the Web API using httpbin.

Use the GET method to obtain the IP address and test the GET request. The curl command makes a GET request if you don’t specify any options.


  • Obtain IP address

request

curl http://httpbin.org/ip

response

{
  "origin": "111.111.111.111" # ip address is different for each
}


  • GET request test

request

curl http://httpbin.org/get

response

{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.68.0",
    "X-Amzn-Trace-Id": "Root=1-5f4f2fa5-80f8b602a2eec73861aa12e8"
  },
  "origin": "111.111.111.111",
  "url": "http://httpbin.org/get"
}


  • POST request test

To make a POST request, specify the HTTP method with the option -X of the curl command. You can describe the data to be included in the POST request with -d. In httpbin, the data included in the request is set in the return value ““form”. When sending JSON, it is necessary to specify Content-Type. Use the request header option -H`.

request

curl -X POST -H'Content-Type: application/json' -d "name=foge&type=fogefoge" http://httpbin.org/post

response

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "name": "foge"
    "type": "fogefoge"
  },
  "headers": {
    "Accept": "*/*",
    "Content-Length": "9",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.68.0",
    "X-Amzn-Trace-Id": "Root=1-5f4f32d3-65c03ae0882434bae32b8070"
  },
  "json": null,
  "origin": "111.111.111.111",
  "url": "http://httpbin.org/post"
}

Hit Web API on Android

On Android, it is not possible to format and display the response result as easily as the curl command. I think it’s better to hit the WebAPI on Android while confirming whether the proper URL can be specified by using the curl command and whether the correct output has been made. This time, I’d like to get the necessary information on Android while using the result of curl executed above.

First, to connect to the Internet, write the following in AndroidManifest.xml.

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

HttpURLConnection

Before starting communication, you need to set some connection settings. It is summarized in the table below.

Connection settings Description
Connection timeout Limit on the time allowed to connect with the connect method.
Read timeout Time required for data acquisition (time until request is made and response is returned)
User-Agent Stores information such as the software and OS making the request (hereiseasytounderstand)
Accept-Language Shows which languages the client understands and what type of locale is recommended
HTTP method For telling the server what to do
Permission to send request body Permission to store and send data in request body
Permission to receive response body Permission to receive data stored in response body

Now, let’s show a program that actually uses HTTP communication using HttpURLConnection. Since HttpURLConnection cannot be executed on the UI thread, it is necessary to create and execute another thread. First, make a GET request to get the IP address.

public String getAPI(){
    HttpURLConnection urlConnection = null;
    InputStream inputStream = null;
    String result = "";
    String str = "";try {
        URL url = new URL("http://httpbin.org/ip");
        // Open the connection to the destination URL. Not connected yet
        urlConnection = (HttpURLConnection) url.openConnection();
        // Set connection timeout
        urlConnection.setConnectTimeout(10000);
        // Set response data read timeout
        urlConnection.setReadTimeout (10000);
        // Set User-Agent in header
        urlConnection.addRequestProperty("User-Agent", "Android");
        // Set Accept-Language in the header
        urlConnection.addRequestProperty ("Accept-Language", Locale.getDefault (). ToString ());
        // Specify HTTP method
        urlConnection.setRequestMethod("GET");
        // Do not allow sending request body
        urlConnection.setDoOutput (false);
        // Allow reception of response body
        urlConnection.setDoInput(true);
        // start communication
        urlConnection.connect();
        // get the response code
        int statusCode = urlConnection.getResponseCode();
        // Response code 200 indicates that communication was successful
        if (statusCode == 200) {
            inputStream = urlConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader (new InputStreamReader (inputStream, "utf-8"));
            // Get response result line by line and add to str
            result = bufferedReader.readLine();
            while (result != null){
                str + = result;
                result = bufferedReader.readLine();
            }
            bufferedReader.close();
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // Return JSON of response result as String type
    return str;
}

Next, make a POST request.

public String postAPI(){
    HttpURLConnection urlConnection = null;
    InputStream inputStream = null;
    OutputStream outputStream = null;
    String result = "";
    String str = "";
    try {
        URL url = new URL("http://httpbin.org/post");
        // Open the connection to the destination URL. Not connected yet
        urlConnection = (HttpURLConnection) url.openConnection();
        // Data to store in the request body
        String postData = "name=foge&type=fogefoge";
        // set connection timeout
        urlConnection.setConnectTimeout(10000);
        // Set response data read timeout
        urlConnection.setReadTimeout(10000);
        // Set User-Agent in header
        urlConnection.addRequestProperty("User-Agent", "Android");
        // Set Accept-Language in the header
        urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
        // Specify HTTP method
        urlConnection.setRequestMethod("POST");
        // Allow reception of response body
        urlConnection.setDoInput(true);
        // allow sending request body
        urlConnection.setDoOutput(true);
        // Start communication
        urlConnection.connect();
        // write the request body
        outputStream = urlConnection.getOutputStream ();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
        bufferedWriter.write(postData);
        bufferedWriter.flush();
        bufferedWriter.close();
        
        // get the response code
        int statusCode = urlConnection.getResponseCode ();
        // Response code 200 indicates that communication was successful
        if (statusCode == 200){
            inputStream = urlConnection.getInputStream ();
            BufferedReader bufferedReader = new BufferedReader (new InputStreamReader (inputStream));
            // Get response result line by line and add to str
            result = bufferedReader.readLine();
            while (result != null){
                str + = result;
                result = bufferedReader.readLine();
            }
            bufferedReader.close();
        }
        urlConnection.disconnect();
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // Return JSON of response result as String type
    return str;
}

JSON processing

As a result of the HTTP communication described above, JSON can be obtained as a character string. Generate a JSON object from the character string and extract the contents.


Extract IP address from return value of GET request

// Get the return value of the GET request function. See the implementation of the GET request above.
response = getAPI();
// Generate a JSON object from the character string and use this as the root.
JSONObject rootJSON = new JSONObject(response);
// See the output result when requesting http://httpbin.org/ip with curl
// Get the value (character string) of the key "origin" directly under the route
ip = rootJSON.getString("origin");

** Extract the value set in the request body from the return value of POST request ** From the output result of making a POST request with the curl command, you can see that the value set in the request body is stored in "form". Extract the value of the request body stored in " form ".

// Get the return value of the POST request function. See the implementation of POST request above.
response = getPOST();
// Generate a JSON object from the character string and use this as the root.
JSONObject rootJSON = new JSONObject(response);
// Get the "form" JSONObject directly under the route
JSONObject formJSON = rootJSON.getJSONObject("form");
// Get the value (character string) of "name"key and "type"key directly under "form"JSONObject
nameAndType = formJSON.getString ("name") + "/" + formJSON.getString ("type");

Based on the above, the sample code is shown.

Sample code

AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package = "com.example.samplehttpconnection">
    <uses-permission android:name="android.permission.INTERNET"/>

    <applicationandroid:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.java


package com.example.samplehttpconnection;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
    private Handler handler = new Handler();
    private Button button;
    private Button button2;
    private TextView textView;
    private TextView textView2;
    private String urlIpText = "http://httpbin.org/ip";
    private String urlPostText = "http://httpbin.org/post";
    private String ip = "";
    private String nameAndType = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.button);
        button2 = findViewById(R.id.button2);
        textView = findViewById(R.id.textView);
        textView2 = findViewById(R.id.textView2);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String response = "";
                        try {
                            response = getAPI();
                            JSONObject rootJSON = new JSONObject(response);
                            ip = rootJSON.getString("origin");
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                textView.setText(ip);
                            }
                        });
                    }
                });
                thread.start();
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Thread thread = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String response = "";
                        try {
                            response = postAPI();
                            JSONObject rootJSON = new JSONObject(response);
                            JSONObject formJSON = rootJSON.getJSONObject("form");
                            nameAndType = formJSON.getString("name") + "/" + formJSON.getString("type");
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                textView2.setText(nameAndType);
                            }
                        });

                    }
                });
                thread.start();
            }
        });
    }

    public String getAPI(){
        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        String result = "";
        String str = "";
        try {
            URL url = new URL(urlIpText);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setConnectTimeout(10000);
            urlConnection.setReadTimeout(10000);
            urlConnection.addRequestProperty("User-Agent", "Android");
            urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(false);
            urlConnection.connect();
            int statusCode = urlConnection.getResponseCode();
            if (statusCode == 200){inputStream = urlConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
                result = bufferedReader.readLine();
                while (result != null){
                    str += result;
                    result = bufferedReader.readLine();
                }
                bufferedReader.close();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

    public String postAPI(){
        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        String result = "";
        String str = "";
        try {
            URL url = new URL(urlPostText);
            urlConnection = (HttpURLConnection) url.openConnection();
            String postData = "name=foge&type=fogefoge";
            urlConnection.setConnectTimeout(10000);
            urlConnection.setReadTimeout(10000);
            urlConnection.addRequestProperty("User-Agent", "Android");
            urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.connect();
            outputStream = urlConnection.getOutputStream();
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
            bufferedWriter.write(postData);
            bufferedWriter.flush();
            bufferedWriter.close();

            int statusCode = urlConnection.getResponseCode();
            if (statusCode == 200){
                inputStream = urlConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                result = bufferedReader.readLine();
                while (result != null){
                    str += result;
                    result = bufferedReader.readLine();
                }
                bufferedReader.close();
            }

            urlConnection.disconnect();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }

}

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="Hello World!"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button2" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="GET"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:text="Hello World!"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="POST"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/button" />

</androidx.constraintlayout.widget.ConstraintLayout>

参照してもらいたいページ