[PYTHON] * Android * [HTTP-Kommunikation_2] HTTP-Kommunikation mit Flask (Web-API [GET, POST] drücken)

Einführung

Im vorherigen Artikel (https://qiita.com/f-paico/items/f03f48d3ecacba7dcc13) habe ich erklärt, wie HttpURLConnection mit httpbin als Web-API verwendet wird. Dieses Mal werden wir Flask als Web-API verwenden und eine HTTP-Kommunikation (GET / POST) zwischen Android und Flask durchführen. Eine ausführliche Erläuterung der Befehle HttpURLConnection und curl finden Sie unter Vorheriger Artikel.

Annahme

*Android Studio 4.0.1 *targetSdkVersion 28 *Google Nexus 5x

Curl-Befehl, Python *Ubuntu 20.04 LTS (WSL 2) *Python 3.7.3

GET-Methode

Die HTTP-Kommunikation mit der GET-Methode kann leicht realisiert werden. Informationen zur Android-Seite finden Sie unter Vorheriger Artikel. Der Code auf der Android-Seite wird auch in den am Ende gezeigten Beispielcode geschrieben. Hier beschreiben wir die Kolbenseite.

app.py


from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/get', methods=['GET'])
def get():
    #Erstellen Sie eine Antwort auf eine GET-Anfrage
    response = {'result': 'success', 'status': 200}
    #Rückgabe als JSON-Objekt
    return jsonify(response)

Senden wir eine Anfrage mit dem Befehl curl.

curl http://127.0.0.1:5000/api/get

Die folgende Antwort sollte ausgegeben werden.

{
  "result": "success",
  "status": 200
}

POST-Methode

In diesem Abschnitt wird die HTTP-Kommunikation mit der POST-Methode beschrieben.

Lesen Sie die Daten im JSON-Format mit dem Kolben

Es gibt drei Möglichkeiten, Daten im JSON-Format zu lesen. Dieses Mal werden die von der POST-Anforderung empfangenen Daten gelesen.

app.py


from flask import Flask, request, jsonify
import json

app = Flask(__name__)

@app.route('/api/post', methods=['POST'])
def post():
    #Methode 1
    #Fordern Sie die von POST empfangenen Daten an.Wenn Sie Daten abrufen, sehen Sie, dass es sich um einen Bytetyp handelt.
    print(type(request.data))
    #Selbst wenn Sie es ausgeben, können Sie sehen, dass es sich um einen Bytetyp handelt
    print(request.data)
    #Da es sich um einen Bytetyp handelt, dekodieren Sie ihn, um ihn in eine Zeichenfolge zu konvertieren
    print(request.data.decode('utf-8'))
    #Im JSON-Format geschriebene Zeichenfolgen können mit der Methode load in den Wörterbuchtyp konvertiert werden
    data = json.loads(request.data.decode('utf-8'))
    print(data)
    
    #Methode 2
    #Bei der Lademethode können zusätzlich zur Zeichenfolge der Bytetyp und der Bytearray-Typ eingefügt werden.
    data = json.loads(request.data)
    print(data)
    
    #Methode 3
    # request.Mit der json-Methode können die vom POST empfangenen Daten als Wörterbuchtyp behandelt werden.
    #Dies ist der schnellste Weg zu schreiben, daher empfehle ich es.
    print(request.json)
    
    #Übernehmen Sie Methode 3 und geben Sie ein JSON-Objekt als Rückgabewert zurück
    data = request.json
    return jsonify(data)
    
    
if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

Führen Sie app.py aus und versuchen Sie, eine POST-Anfrage mit curl zu senden. Öffnen Sie ein neues Terminal und führen Sie den folgenden Befehl aus. Der Textkörper beschreibt eine Zeichenfolge im JSON-Format.

curl -X POST -H 'Content-Type:application/json' -d `{"name": "foge", "value": "fogefoge"}` http://127.0.0.1:5000/api/post

Wenn der Befehl curl ausgeführt wird, wird Folgendes an das Terminal ausgegeben, auf dem app.py ausgeführt wird. Es kann bestätigt werden, dass die Ausgabe der unteren drei Zeilen gleich ist.

<class 'bytes'>
b'{"name": "foge", "value": "fogefoge"}'
{"name": "foge", "value": "fogefoge"}
{'name': 'foge', 'value': 'fogefoge'}
{'name': 'foge', 'value': 'fogefoge'}
{'name': 'foge', 'value': 'fogefoge'}

Json-Format auf Android

Um die Daten der Zeichenfolge zu lesen, die im JSON-Format geschrieben wurde und von Android in Python gesendet wurde, muss Android den Körper gemäß dem JSON-Format beschreiben. Gehen Sie insbesondere wie folgt vor.

String postData = "{\"name\": \"foge\", \"value\": \"fogefoge\"}";

Auf diese Weise wird, da doppelte Anführungszeichen in der Zeichenfolge beschrieben werden müssen, eine Escape-Sequenz verwendet. Wenn Sie variable Daten in eine Zeichenfolge einbetten möchten, schreiben Sie wie folgt.

String name = "foge";
int value = 100;

String postData = String.format("{\"name\": \"%s\", \"value\": %d}", name, value);

Da es jedoch sehr mühsam ist, auf diese Weise zu beschreiben, wird es im Allgemeinen wie folgt beschrieben.

//Erstellen Sie ein assoziatives Array
HashMap<String, Object> jsonMap = new HashMap<>();
jsonMap.put("name", "foge");
jsonMap.put("value", 100);
//Konvertieren Sie das assoziative Array in JSONObject
JSONObject responseJsonObject = new JSONObject(jsonMap);
//Konvertieren Sie JSONObject in einen String
String postData = responseJsonObject.toString();

Beispielcode

Anschließend wird der Beispielcode unten angezeigt.

app.py


from flask import Flask, request, jsonify

app = Flask(__name__)
#Wenn das jsonify-Ergebnis Japanisch enthält, können Sie verstümmelte Zeichen vermeiden, indem Sie die folgende Zeile schreiben.
app.config['JSON_AS_ASCII'] = False


@app.route('/api/get', methods=['GET'])
def get():
    response = {"result": "success", "status": 200}
    return jsonify(response)
    

@app.route('/api/post', methods=['POST'])
def post():
    data = request.json
    name = data['name']
    value = data['value']
    array = data['array']
    print(f'data: {data}')
    print(f'data["name"]: {name}')
    print(f'data["value"]: {value}')
    print(f'data["array"]: {array}')
    print(f'data["array[0]"]: {array[0]}')
    print(f'data["array[1]"]: {array[1]}')
    print(f'data["array[2]"]: {array[2]}')
    return jsonify(data)
    
    
if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

Überprüfen Sie vor dem Schreiben des Android-Beispielcodes, ob eine HTTP-Kommunikation einmal mit curl möglich ist.

curl http://127.0.0.1:5000/api/get
curl -X POST -H 'Content-Type:application/json' -d '{"name": "foge", "value": 100, "array":["Guten Morgen", "Hallo", "Guten Abend"]}' http://127.0.0.1:5000/api/post

Der Beispielcode für Android ist unten dargestellt.

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>

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:gravity="center"
        android:text=""
        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:gravity="center"
        android:text=""
        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>

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.ArrayList;
import java.util.HashMap;
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;
    //Bitte ändern Sie Ihre IP-Adresse. Beschreiben Sie die IP-Adresse des PCs, auf dem das Python-Programm ausgeführt wird
    private String urlGetText = "http://192.168.0.10:5000/api/get";
    private String urlPostText = "http://192.168.0.10:5000/api/post";
    private String getResultText = "";
    private String postResultText = "";

    @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);
                            getResultText = rootJSON.toString();
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                textView.setText(getResultText);
                            }
                        });
                    }
                });
                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);
                            postResultText = rootJSON.toString();
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                textView2.setText(postResultText);
                            }
                        });
                    }
                });
                thread.start();
            }
        });
    }

    public String getAPI(){
        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        String result = "";
        String str = "";
        try {
            URL url = new URL(urlGetText);
            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();
            urlConnection.setConnectTimeout(10000);
            urlConnection.setReadTimeout(10000);
            urlConnection.addRequestProperty("User-Agent", "Android");
            urlConnection.addRequestProperty("Accept-Language", Locale.getDefault().toString());
            urlConnection.addRequestProperty("Content-Type", "application/json; charset=UTF-8");
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.connect();
            outputStream = urlConnection.getOutputStream();

            HashMap<String, Object> jsonMap = new HashMap<>();
            jsonMap.put("name", "foge");
            jsonMap.put("value", 100);
            ArrayList<String> array = new ArrayList<>();
            array.add("Guten Morgen");
            array.add("Hallo");
            array.add("Guten Abend");
            jsonMap.put("array", array);
            JSONObject responseJsonObject = new JSONObject(jsonMap);
            String jsonText = responseJsonObject.toString();
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "utf-8"));
            bufferedWriter.write(jsonText);
            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;
    }
}

Seite, die Sie sehen möchten

Recommended Posts

* Android * [HTTP-Kommunikation_2] HTTP-Kommunikation mit Flask (Web-API [GET, POST] drücken)
HTTP-Kommunikation mit Python
GET / POST-Kommunikation von Flask (auch über CORS-Unterstützung)
Vergleichen Sie HTTP GET / POST mit cURL (Befehl) und Python (Programmierung).
Holen Sie sich ein Kommunikationsmemo in Python
Post Bulletin Board Erstellung mit Flasche
POST verschieden mit Python und empfange mit Flask
(Für mich) Flask_3 (Formular, POST und GET)
Wenn Sie sich mit HTTP-Weiterleitungen 301 und 302 verlaufen