* Android * [HTTP communication_1] Try hitting WebAPI [GET, POST]

Introduction

Hello. This time, let's hit the Web API 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 WebAPI, but use the Java standard library HttpURLConnection. There are no complicated settings, and I think it is an orthodox method if it is used to hit the Web API.

If you hit WebAPI, you will receive JSON as a return value, but since it is difficult to format JSON and output it to the screen on Android, we will implement Android while using the curl command. I will. When using WebAPI, I think that it will be much easier to work with 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 the web API

If you want to make a music lyrics app or a translation app. It takes time and effort to collect data on the lyrics of music that increases in real time, and to collect the data to create a translation function. If it is difficult to make it yourself, I think you will use the library. What to do if you cannot find the standard library or external library even if you search for them. What to do 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 the Web API.

WebAPI is not language-dependent and is often linked to a database, so it is good at handling real-time data and huge amounts of data. Internet connection is a prerequisite for using HTTP communication, but in the case of Android, it is natural that you can always connect to the Internet, so there is no problem even if you create an application using Web API. Note that you need to be careful when the Web API cannot be used temporarily due to maintenance or the specifications are changed.

How to use WebAPI

If you explain it strictly, it will be difficult to understand, so if you explain roughly while making the meaning of each term a little vague, WebAPI refers to the part or interface of a Web service that is allowed to be accessed by the developer from the program. Accessing the WebAPI programmatically is called a request, and returning the result of the request is called a response. To send a request, you need to specify the URL and HTTP method. The HTTP method uses the most basic GET and POST. The specifics of how to send the request and what the response will be are as follows.

request

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

response

{
    "name": "foge"
}

In this way, when you make a request, the response will be returned in the form JSON. The GET method is mainly used to get the data, and the POST method is mainly used when you want to include the data in the request and send it.

Which Web API to use

--The easiest way to test HTTP communication is to use httpbin HP. Normally, registration and API key acquisition are required to use WebAPI, but httpbin's HP does not require them. You can try HTTP communication without registration. This time we will use this. ――I won't explain it in this article, but if you want to try registration and API key acquisition, I think you should use OpenWeatherMap, which is easy to acquire API key. .. Getting the current weather in Tokyo is explained on various web pages, so you can easily try it.

About httpbin

Various tests can be performed by adding the specified parameters after the URL http://httpbin.org. This time, we will use the following functions.

function URL
Obtaining an IP address http://httpbin.org/ip
GET request test http://httpbin.org/get
Testing POST request http://httpbin.org/post

curl command

If you want to use the curl command on Windows, install WSL2 or install the curl command for Windows. WSL2 is the easiest way to use the 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 a variety of purposes, but it is often used when making HTTP requests. Now, let's actually hit the Web API using httpbin.

Use the GET method to get the IP address and test the GET request. The curl command makes a GET request if no options are added.


--Getting an IP address

request

curl http://httpbin.org/ip

response

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

--Testing GET request

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"
}

--Testing POST request

To make a POST request, specify the HTTP method with the option -X of the curl command. With -d, you can describe the data to be included in the POST request. 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 the 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 is better to hit the Web API on Android while checking whether the appropriate URL can be specified by using the curl command and whether the output is correct. This time, I would like to get the necessary information on Android while using the result of curl executed above.

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

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

HttpURLConnection

You need to make some connection settings before starting communication. It is summarized in the table below.

Connection settings Description
Connection timeout Limitation on the time it may take to connect with the connect method.
Read timeout Time taken to acquire data (time required to make a request and return a response)
User-Agent Stores information such as software and OS that make requests(HereIseasytounderstand)
Accept-Language Indicates which language the client can understand and what kind of locale is recommended
HTTP method To tell the server what you want it to do
Permission to send request body Permission to store and send data in the request body
Response body reception permission Permission to receive data stored in the response body

Now, let's show a program that actually performs HTTP communication using HttpURLConnection. Since HttpURLConnection cannot be executed in the UI thread, it is necessary to create another thread and execute it. 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 a 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);
        //User in header-Set Agent
        urlConnection.addRequestProperty("User-Agent", "Android");
        //Accept in header-Set Language
        urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
        //Specify HTTP method
        urlConnection.setRequestMethod("GET");
        //Do not allow submission of request body
        urlConnection.setDoOutput(false);
        //Allow reception of response body
        urlConnection.setDoInput(true);
        //Start communication
        urlConnection.connect();
        //Get 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 the response result line by line and add it 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 a connection to the destination URL. Not connected yet
        urlConnection = (HttpURLConnection) url.openConnection();
        //Data to be stored in the request body
        String postData = "name=foge&type=fogefoge";
        //Set connection timeout
        urlConnection.setConnectTimeout(10000);
        //Set response data read timeout
        urlConnection.setReadTimeout(10000);
        //User in header-Set Agent
        urlConnection.addRequestProperty("User-Agent", "Android");
        //Accept in header-Set Language
        urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
        //Specify HTTP method
        urlConnection.setRequestMethod("POST");
        //Allow reception of response body
        urlConnection.setDoInput(true);
        //Allow submission of 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 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 the response result line by line and add it 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 mentioned above, JSON can be acquired as a character string. Create a JSON object from the character string and extract the contents.


** Extract the IP address from the return value of the GET request **

//Get the return value of the GET request function. See the implementation of the GET request above.
response = getAPI();
//Create a JSON object from a character string and use this as the root.
JSONObject rootJSON = new JSONObject(response); 
//http with curl://httpbin.org/Refer to the output result when requesting to ip
//Just below the route"origin"Get the value (character string) of the key
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 confirm 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 POST request implementation above.
response = getPOST();
//Create a JSON object from a character string and use this as the root.
JSONObject rootJSON = new JSONObject(response);
//Just below the route"form"Get JSONObject
JSONObject formJSON = rootJSON.getJSONObject("form");
// "form"Directly under JSONObject"name"with key"type"Get the key value (string)
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"/>

    <application
        android: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>

Page you want to see

-Next article

Recommended Posts

* Android * [HTTP communication_1] Try hitting WebAPI [GET, POST]
OkHttp3 (GET, POST) in Android Studio
Try communication using gRPC on Android + Java server
HTTP / HTTPS communication
[Java] How to get a request by HTTP communication