[PYTHON] * Android * [Communication HTTP_2] Communication HTTP avec Flask (appuyez sur API Web [GET, POST])

introduction

Dans Article précédent, j'ai expliqué comment utiliser HttpURLConnection en utilisant httpbin comme API Web. Cette fois, nous utiliserons Flask comme API Web et effectuerons une communication HTTP (GET / POST) entre Android et Flask. Pour une explication détaillée des commandes HttpURLConnection et curl, reportez-vous à Article précédent.

supposition

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

commande curl, Python *Ubuntu 20.04 LTS (WSL 2) *Python 3.7.3

Méthode GET

La communication HTTP utilisant la méthode GET peut être facilement réalisée. Pour le côté Android, veuillez vous référer à Article précédent. Le code côté Android est également écrit dans l'exemple de code affiché à la fin. Ici, nous décrirons le côté Flask.

app.py


from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/get', methods=['GET'])
def get():
    #Créer une réponse à une requête GET
    response = {'result': 'success', 'status': 200}
    #Retour en tant qu'objet JSON
    return jsonify(response)

Envoyons une requête en utilisant la commande curl.

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

La réponse suivante doit être sortie.

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

Méthode POST

Cette section décrit la communication HTTP à l'aide de la méthode POST.

Lire les données au format JSON avec flask

Il existe trois façons de lire les données au format JSON. Cette fois, les données reçues par la requête POST seront lues.

app.py


from flask import Flask, request, jsonify
import json

app = Flask(__name__)

@app.route('/api/post', methods=['POST'])
def post():
    #Méthode 1
    #Demander les données reçues par POST.Si vous récupérez les données, vous pouvez voir qu'il s'agit d'un type d'octets.
    print(type(request.data))
    #Même si vous le sortez, vous pouvez voir qu'il s'agit d'un type d'octets
    print(request.data)
    #Puisqu'il s'agit d'un type d'octets, décodez-le pour le convertir en chaîne de caractères
    print(request.data.decode('utf-8'))
    #Les chaînes de caractères écrites au format JSON peuvent être converties en type dictionnaire par la méthode charges
    data = json.loads(request.data.decode('utf-8'))
    print(data)
    
    #Méthode 2
    #Dans la méthode de chargement, le type d'octets et le type de tableau d'octets peuvent être insérés en plus de la chaîne de caractères.
    data = json.loads(request.data)
    print(data)
    
    #Méthode 3
    # request.En utilisant la méthode json, les données reçues par POST peuvent être traitées comme un type de dictionnaire.
    #C'est le moyen le plus rapide d'écrire, donc je le recommande.
    print(request.json)
    
    #Adoptez la méthode 3 et renvoyez un objet JSON comme valeur de retour
    data = request.json
    return jsonify(data)
    
    
if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

Exécutez app.py et essayez d'envoyer une requête POST à l'aide de curl. Ouvrez un nouveau terminal et exécutez la commande suivante. Le corps décrit une chaîne de caractères au format JSON.

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

Lorsque la commande curl est exécutée, ce qui suit est envoyé au terminal où app.py est exécuté. Il peut être confirmé que la sortie des trois dernières lignes est la même.

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

Format Json sur Android

Afin de lire les données de la chaîne de caractères écrite au format JSON envoyée depuis Android en Python, il est nécessaire de décrire le corps conformément au format JSON sur Android. Plus précisément, procédez comme suit.

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

De cette façon, puisqu'il est nécessaire de décrire des guillemets doubles dans la chaîne de caractères, elle est décrite à l'aide d'une séquence d'échappement. Si vous souhaitez incorporer des données variables dans une chaîne de caractères, écrivez comme suit.

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

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

Cependant, comme il est très difficile de le décrire de cette manière, il est généralement décrit comme suit.

//Créer un tableau associatif
HashMap<String, Object> jsonMap = new HashMap<>();
jsonMap.put("name", "foge");
jsonMap.put("value", 100);
//Convertir un tableau associatif en JSONObject
JSONObject responseJsonObject = new JSONObject(jsonMap);
//Convertir JSONObject en chaîne
String postData = responseJsonObject.toString();

Exemple de code

Ensuite, l'exemple de code est illustré ci-dessous.

app.py


from flask import Flask, request, jsonify

app = Flask(__name__)
#Si le résultat jsonify contient du japonais, vous pouvez éviter les caractères déformés en écrivant la ligne suivante.
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)

Avant d'écrire l'exemple de code Android, veuillez vérifier si la communication HTTP est possible une fois avec curl.

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

L'exemple de code Android est illustré ci-dessous.

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;
    //Veuillez changer votre adresse IP. Décrivez l'adresse IP du PC exécutant le programme Python
    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("Bonjour");
            array.add("Bonjour");
            array.add("Bonsoir");
            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;
    }
}

Page que vous voulez voir

Recommended Posts

* Android * [Communication HTTP_2] Communication HTTP avec Flask (appuyez sur API Web [GET, POST])
Communication HTTP avec Python
Communication GET / POST par Flask (également à propos du support CORS)
Comparez HTTP GET / POST avec cURL (commande) et Python (programmation)
Obtenir, publier un mémo de communication en Python
Création d'un babillard avec flask
POSTER diversement avec Python et recevoir avec Flask
(Pour moi) Flask_3 (formulaire, POST et GET)
Si vous vous perdez avec les redirections HTTP 301 et 302