Erstellen Sie einen SlackBot mit AWS Lambda & API Gateway in Java

Einführung

Wenn ich einen Slack-Bot mache, denke ich, dass ich in den meisten Fällen Python oder Node.js verwenden werde, aber dieses Mal werde ich es wagen, mit Java zu arbeiten. Ich konnte keinen Artikel über das Erstellen eines serverlosen Slack-Bots über AWS mit Java in Japanisch oder Englisch finden. Daher werde ich das Implementierungsverfahren hier schreiben. Ich bin ein Amateur, wenn es um Java geht, also ist es besser, dies zu tun! Ich würde mich freuen, wenn Sie auf Punkte hinweisen könnten. Der ganze Code ist auf Github https://github.com/kamata1729/sampleSlackBotWithJava

Erstellen eines Slack Bot

Erstellen Sie eine App zum Erstellen von Bot

Lassen Sie uns zuerst einen Slack Bot machen! https://api.slack.com/apps Klicken Sie hier auf Neue App erstellen, um eine neue App zu erstellen. image.png

Und füge Bot User zur erstellten App hinzu image.png

Erstellen Sie einen Endpunkt, um Slack-Ereignisse zu empfangen

Von hier aus erstellen wir einen Endpunkt, um Ereignisse von Slack on AWS zu empfangen. Insbesondere empfängt API Gateway das Ereignis und übergibt es an die Lambda-Funktion.

Erstellen einer IAM-Rolle

Öffnen Sie IAM über die AWS-Konsole und erstellen Sie eine neue Rolle. image.png

Da es in Lambda verwendet wird, wählen Sie "Lambda" und fahren Sie zuerst fort. image.png

Dieses Mal möchte ich das Protokoll in das CloudWatch-Protokoll ausgeben können. Wählen Sie daher "AWSLambdaBasicExecutionRole" mit Schreibberechtigung aus ` image.png

Ich werde es dieses Mal nicht zum Erstellen des nächsten Tags verwenden, sodass Sie es ignorieren können. Geben Sie im nächsten Bestätigungsbildschirm einen Rollennamen ein und Sie sind fertig! Dieses Mal habe ich es "sampleBotRole" genannt. image.png

Erstellen einer Lambda-Funktion

Gehen Sie nun zur Lambda-Konsole und erstellen Sie eine Funktion. Wählen Sie "Von Grund auf neu erstellen", diesmal "sampleBot" als Funktionsnamen und "Java 8" als Laufzeit. Außerdem habe ich für die Rolle die zuvor erstellte "sampleBotRole" ausgewählt. image.png

API-Gateway erstellen

Wählen Sie zunächst "API erstellen" auf der Seite "API-Gateway" der aws-Konsole aus und erstellen Sie sie mit dem API-Namen (diesmal "sampleBotAPI"). image.png Wählen Sie im erstellten Bildschirm "Aktion-> Methode erstellen", um die "POST" -Methode hinzuzufügen. image.png Drücken Sie das Häkchen, um eine POST-Methode zu erstellen, stellen Sie sie so ein, dass sie mit der zuvor auf dem Setup-Bildschirm erstellten Lambda-Funktion übereinstimmt, und speichern Sie sie. image.png Wählen Sie im folgenden Bildschirm "Aktion-> API bereitstellen" und geben Sie den zu bereitstellenden Stufennamen ein. Zu diesem Zeitpunkt wird die URL zum Aufrufen des Endpunkts oben auf dem Bildschirm angezeigt. Notieren Sie sich diese. Damit ist die Endpunkterstellung abgeschlossen! image.png

Informationen zur Authentifizierung der Slack Event API

Lassen Sie uns vor der Implementierung der Lambda-Funktion über die Authentifizierung der Slack-Event-API sprechen. Bei der Slack-Ereignis-API müssen Sie zuerst eine bestimmte Zeichenfolge zurücksenden, um festzustellen, ob das Programm für die Ereignis-API vorgesehen ist.

Zur Authentifizierung wird zuerst der folgende JSON gesendet.

{
    "token": "Jhj5dZrVaK7ZwHHjRyZWjbDl",
    "challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
    "type": "url_verification"
}

Wenn andererseits der Inhalt von "Herausforderung" innerhalb von 3 Sekunden zurückgesendet werden kann, ist die Authentifizierung abgeschlossen. Es gibt drei Formate zum Zurücksenden. Weitere Informationen finden Sie unter https://api.slack.com/events/url_verification.

HTTP 200 OK
Content-type: text/plain
3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P
HTTP 200 OK
Content-type: application/x-www-form-urlencoded
challenge=3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P
HTTP 200 OK
Content-type: application/json
{"challenge":"3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P"}

Informationen zur Eingabe / Ausgabe von AWS Lambda

Wenn Sie AWS Lambda I / O in Java definieren, müssen Sie eine Handler-Implementierung implementieren, die auf drei Arten erfolgen kann. Ich werde es hier kurz schreiben, aber siehe unten für Details https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/java-programming-model-handler-types.html https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/java-handler-using-predefined-interfaces.html

1. Laden Sie die Handler-Methode direkt

Es werden die standardmäßig implementierten Typen verwendet, ohne dass spezielle Eingabe- / Ausgabetypen definiert werden. Implementieren Sie wie folgt


outputType handler-name(inputType input, Context context) {
   ...
}

Es scheint, dass der "inputType", "outputType" standardmäßig String-Typ, Integer-Typ, Boolescher Typ, Map-Typ und Listentyp unterstützt. (Einzelheiten siehe unten https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/java-programming-model-req-resp.html)

Beispielsweise ist die folgende Implementierung möglich

package example;

import com.amazonaws.services.lambda.runtime.Context; 

public class Hello {
    public String myHandler(String name, Context context) {
        return String.format("Hello %s.", name);
    }
}

2. Verwenden Sie den Typ POJO

Wenn Sie Ihren eigenen Typ für "inputType" und "outputType" angeben möchten, können Sie auch den Typ definieren und verwenden, der dem Eingabe- / Ausgabeformat entspricht.

Dies kann wie folgt implementiert werden:

package example;

import com.amazonaws.services.lambda.runtime.Context; 

public class HelloPojo {

    // Define two classes/POJOs for use with Lambda function.
    public static class RequestClass {
      ...
    }

    public static class ResponseClass {
      ...
    }

    public static ResponseClass myHandler(RequestClass request, Context context) {
        String greetingString = String.format("Hello %s, %s.", request.getFirstName(), request.getLastName());
        return new ResponseClass(greetingString);
    }
}

3. Verwenden Sie RequestStreamHandler

Es gibt auch eine Möglichkeit, Ein- und Ausgänge mit "InputStream" und "OutputStream" zu aktivieren. Sie können antworten, indem Sie eine Byte-Zeichenfolge in "OutputStream" schreiben. Ein Beispiel ist ein Programm, das eine bestimmte Zeichenfolge großschreibt und zurückgibt.

package example;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.amazonaws.services.lambda.runtime.Context; 

public class Hello implements RequestStreamHandler {
    // if input is "test", then return "TEST"
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context)
            throws IOException {
        int letter;
        while((letter = inputStream.read()) != -1)
        {
            outputStream.write(Character.toUpperCase(letter));
        }
    }
}

Dieses Mal ist es schwierig, verschachtelte Jsons im POJO-Typ zu empfangen, daher verwende ich RequestStreamHandler.

Machen Sie die Lambda-Funktion kompatibel mit der Slack-Authentifizierung

Basierend auf dem oben Gesagten werden wir die Lambda-Funktion codieren, aber im Gegensatz zu Python usw. kann der Code im Fall von Java nicht inline bearbeitet werden. Daher werde ich dieses Mal ein Java-Projekt mit lokalem Maven erstellen und es mit gradle in eine Zip-Datei hochladen.

Ein Projekt erstellen

Erstellen Sie zunächst ein Projekt mit maven. (Maven wird nur zum Erstellen eines Projekts verwendet. Es spielt also keine Rolle, ob Sie es auf andere Weise erstellen.)

$ mvn archetype:generate

Unterwegs werden Sie häufig gefragt, aber mit Ausnahme von "groupId" und "artefaktId" können Sie eingeben. Diesmal ist "groupId" "jp.com.hoge" und "artefaktId" ist "SampleBot". Bei der Ausführung wird ein Ordner mit dem Projektnamen erstellt und "src / main / java / jp / com / hoge / App.java" generiert.

Bearbeiten von App.java

Bearbeiten Sie App.java wie folgt. Selbst wenn Sie den Inhalt von "Herausforderung" nicht erhalten und eine Zeichenfolge nicht zurücksenden, wird dies als Zeitüberschreitung betrachtet und das Ereignis wird nach 1 Minute und 5 Minuten erneut gesendet, daher vorerst "OK" Ich werde mit "antworten.

src/main/java/jp/com/hoge/App.java


package jp.com.hoge;

import java.io.*;
import java.net.URLEncoder;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.lang.StringBuilder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;

import com.amazonaws.services.lambda.runtime.*;

public class App implements RequestStreamHandler
{
    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        //Standardantwort Wenn Sie nichts antworten, wird dasselbe Ereignis mehrmals gesendet
        String response = "HTTP 200 OK\nContent-type: text/plain\nOK";
        try{
            BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); 
            String jsonText = readAll(rd);
            System.out.println(jsonText); //System.Die Ausgabe von out wird in CloudWatch-Protokolle geschrieben
            JSONObject json = new JSONObject(jsonText);
            if (json.has("type")) {
                String eventType = json.get("type").toString();
                if (eventType.equals("url_verification")) {
                    //Stellen Sie den Inhalt der Herausforderung auf Antwort ein
                    response = "HTTP 200 OK\nContent-type: text/plain\n" + json.get("challenge").toString();
                }
            }
        } catch(IOException e) {
            e.printStackTrace();
        } finally {
            //Schreiben Sie den Inhalt der Antwort auf outputStream
            outputStream.write(response.getBytes());
            outputStream.flush();
            outputStream.close();
        }
        return;
    }

    /* get String from BufferedReader */
    private static String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
            sb.append((char) cp);
        }
        return sb.toString();
    }
}

Bearbeiten Sie build.gradle

Platzieren Sie außerdem "build.gradle" direkt unter dem Projektordner. Wenn Sie andere Bibliotheken haben, die Sie verwenden möchten, können Sie diese in "Abhängigkeiten" schreiben oder einen lib-Ordner erstellen und die JAR-Datei darin ablegen.

build.gradle


apply plugin: 'java'

repositories {
    mavenCentral()
}

dependencies {
    compile (
        'com.amazonaws:aws-lambda-java-core:1.1.0',
        'com.amazonaws:aws-lambda-java-events:1.1.0',
        'org.json:json:20180813'
    )
    testCompile 'junit:junit:4.+'
}

task buildZip(type: Zip) {
    from compileJava
    from processResources              
    into('lib') {
        from configurations.compileClasspath
    }           
}

build.dependsOn buildZip

Mit Gradle bauen

Führen Sie zu diesem Zeitpunkt Folgendes direkt unter dem zu erstellenden Projektordner aus.

$ gradle build

Wenn der Build erfolgreich ist, sollte "build / Distribution / SampleBot.zip" generiert werden.

Testausführung der Lambda-Funktion

Öffnen Sie die AWS Lambda-Konsole und laden Sie die soeben erstellte SampleBot.zip hoch. Geben Sie "jp.com.hoge.App" in den Handler ein und vergessen Sie nicht, ihn zu speichern. image.png

Ausführung des Testereignisses

Lassen Sie uns zuerst die Lambda-Funktion testen. Wählen Sie "Testereignis erstellen" aus dem Abwärtspfeil im Feld "Testereignis auswählen ..." oben rechts auf dem Bildschirm und erstellen Sie es wie in der folgenden Abbildung gezeigt.

image.png

Klicken Sie oben rechts auf dem Bildschirm auf die Schaltfläche "Test", um den Test auszuführen. Bei Erfolg wird das Ausführungsergebnis angezeigt. Wenn Sie auf "Details" klicken, wird es wie unten gezeigt angezeigt. Sie können sehen, dass die Ausgabe ordnungsgemäß erfolgt image.png

In CloudWatch wird der Inhalt der inputStream-Ausgabe als Protokoll angezeigt. image.png

Abonnieren Sie die Slack Event API

An diesem Punkt können Sie endlich die Slack Event API abonnieren! Wählen Sie "Ereignisabonnements" auf der linken Seite, wenn Sie den Bot erstellt haben image.png Aktivieren Sie Ereignisse aktivieren und geben Sie die URL, die Sie beim Bereitstellen der API notiert haben, in das Feld URL anfordern ein. Sobald die Antwort bestätigt wurde, sieht sie wie folgt aus und Sie können Ereignisse abonnieren! image.png

Dieses Mal erhalten wir ein Ereignis namens "app_mention". Dies ist ein Ereignis, das reagiert, wenn ein Bot mit einem @ erwähnt wird. Drücken Sie nach dem Hinzufügen auf "Änderungen vergessen" image.png

Bot-Installation

Installieren Sie dann den Bot im Arbeitsbereich Wählen Sie "OAuth & Permissions" und scrollen Sie nach unten zum Menü "Scopes". Wählen Sie "Nachrichten als SampleBot senden" und "Änderungen speichern". Sie können jetzt eine Nachricht als SampleBot senden. image.png

Dann installieren Sie mit "App in Workspace installieren". Das OAuth-Zugriffstoken und das OAuth-Zugriffstoken für Bot-Benutzer werden angezeigt. Notieren Sie sich diese ebenfalls. image.png

Lassen Sie einen Papagei Bot zurückgeben

Von hier aus werde ich ein Beispiel für einen Bot erstellen, der auf eine an mich gerichtete Aussage reagiert, indem er einen Papagei zurückgibt. Der gesamte Quellcode wird auf github veröffentlicht https://github.com/kamata1729/sampleSlackBotWithJava

Das Ereignis "app_mention" wird wie folgt gesendet.

{
    "token": "ZZZZZZWSxiZZZ2yIvs3peJ",
    "team_id": "T061EG9R6",
    "api_app_id": "A0MDYCDME",
    "event": {
        "type": "app_mention",
        "user": "U061F7AUR",
        "text": "What is the hour of the pearl, <@U0LAN0Z89>?",
        "ts": "1515449522.000016",
        "channel": "C0LAN2Q65",
        "event_ts": "1515449522000016"
    },
    "type": "event_callback",
    "event_id": "Ev0LAN670R",
    "event_time": 1515449522000016,
    "authed_users": [
        "U0LAN0Z89"
    ]
}

Erstellen Sie andererseits auf demselben Kanal einen Bot, der "Was ist die Stunde der Perle, <@ U061F7AUR>?" Veröffentlicht, wobei die Erwähnung in den Benutzernamen des anderen Benutzers geändert wird.

Holen Sie sich die Bot-Benutzer-ID

Wir müssen die Benutzer-ID im Text ersetzen, also die Benutzer-ID des Bots abrufen. Holen Sie sich zunächst das Token für den Arbeitsbereich aus dem Folgenden. https://api.slack.com/custom-integrations/legacy-tokens Verwenden Sie dieses Token, um auf die folgende URL zuzugreifen, die ID des Samplebots abzurufen und diese zu notieren. Eine Zeichenfolge, die mit einem oberen U beginnt. https://slack.com/api/users.list?token=取得したtoken

Registrierung von Umgebungsvariablen

Ich habe es als Umgebungsvariable auf der AWS-Lambda-Seite niedergeschrieben.

Registrieren Sie die drei. Sie können es jetzt von der System.getenv-Methode abrufen. image.png

Veröffentlichen Sie eine Nachricht mit der API chat.postMessage

Sie können eine Nachricht veröffentlichen, indem Sie JSON in die API chat.postMessage werfen. Der json zu diesem Zeitpunkt wird auf diese Weise gesendet.

{
    "token": SLACK_APP_AUTH_TOKEN,
    "channel": channel,
    "text": message,
    "username": "sampleBot"
}

Zu diesem Zeitpunkt als Request-Eigenschaft, "Content-Type": "application / json; charset = UTF-8", "Authorization": "Bearer " + SLACK_BOT_USER_ACCESS_TOKEN Muss eingestellt werden.

Basierend auf dem oben Gesagten habe ich App.java wie folgt bearbeitet.

App.java


package jp.com.hoge;

import java.io.*;
import java.net.URLEncoder;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.nio.charset.Charset;
import java.lang.StringBuilder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONArray;

import com.amazonaws.services.lambda.runtime.*;

public class App implements RequestStreamHandler
{
    public static String SLACK_BOT_USER_ACCESS_TOKEN = "";
    public static String SLACK_APP_AUTH_TOKEN = "";
    public static String USER_ID = "";

    @Override
    public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
        //Umgebungsvariablen lesen
        App.SLACK_BOT_USER_ACCESS_TOKEN = System.getenv("SLACK_BOT_USER_ACCESS_TOKEN");
        App.SLACK_APP_AUTH_TOKEN = System.getenv("SLACK_APP_AUTH_TOKEN");
        App.USER_ID = System.getenv("USER_ID");

        //Standardantwort Wenn Sie nichts antworten, wird dasselbe Ereignis mehrmals gesendet
        String response = "HTTP 200 OK\nContent-type: text/plain\nOK";
        try{
            BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); 
            String jsonText = readAll(rd);
            System.out.println(jsonText); //System.Die Ausgabe von out wird in CloudWatch-Protokolle geschrieben
            JSONObject json = new JSONObject(jsonText);

            //Beim Testen der Ereignis-API
            if (json.has("type")) {
                String eventType = json.get("type").toString();
                if (eventType.equals("url_verification")) {
                    //Stellen Sie den Inhalt der Herausforderung auf Antwort ein
                    response = "HTTP 200 OK\nContent-type: text/plain\n" + json.get("challenge").toString();
                }
            }
            
            // app_Zum Zeitpunkt der Erwähnung Veranstaltung
            if (json.has("event")) {
                JSONObject eventObject = json.getJSONObject("event");
                if(eventObject.has("type")) {
                    String eventType = eventObject.get("type").toString();
                    if (eventType.equals("app_mention")){
                        String user = eventObject.get("user").toString();
                        if (user.equals(App.USER_ID)) { return; } //Ignorieren Sie, ob die Anweisung der Bot-Benutzer selbst ist
                        String channel = eventObject.get("channel").toString();
                        String text = eventObject.get("text").toString();
                        String responseText = text.replace(App.USER_ID, user);
                        System.out.println(responseText);
                        System.out.println(postMessage(responseText, channel));
                    }
                }
            }       
        } catch(IOException e) {
            e.printStackTrace();
        } finally {
            //Schreiben Sie den Inhalt der Antwort auf outputStream
            outputStream.write(response.getBytes());
            outputStream.flush();
            outputStream.close();
        }
        return;
    }

    /* get String from BufferedReader */
    private static String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
            sb.append((char) cp);
        }
        return sb.toString();
    }

    /* post message to selected channel */
    public static String postMessage(String message, String channel) {
        String strUrl = "https://slack.com/api/chat.postMessage";
        String ret = "";
        URL url;

        HttpURLConnection urlConnection = null;
        try {
            url = new URL(strUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
        } catch(IOException e) {
            e.printStackTrace();
            return "IOException";
        }
        
        urlConnection.setDoOutput(true);
        urlConnection.setConnectTimeout(100000);
        urlConnection.setReadTimeout(100000);
        urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        String auth = "Bearer " + App.SLACK_BOT_USER_ACCESS_TOKEN;
        urlConnection.setRequestProperty("Authorization", auth);

        try {
            urlConnection.setRequestMethod("POST");
        } catch(ProtocolException e) {
            e.printStackTrace();
            return "ProtocolException";
        }

        try {
            urlConnection.connect();
        } catch(IOException e) {
            e.printStackTrace();
            return "IOException";
        }

        HashMap<String, Object> jsonMap = new HashMap<>();
        jsonMap.put("token", App.SLACK_APP_AUTH_TOKEN);
        jsonMap.put("channel", channel);
        jsonMap.put("text", message);
        jsonMap.put("username", " sampleBot");

        OutputStream outputStream = null;
        try {
            outputStream = urlConnection.getOutputStream();
        } catch(IOException e) {
            e.printStackTrace();
            return "IOException";
        }

        if (jsonMap.size() > 0) {
            JSONObject responseJsonObject = new JSONObject(jsonMap);
            String jsonText = responseJsonObject.toString();
            PrintStream ps = new PrintStream(outputStream);
            ps.print(jsonText);
            ps.close();
        }

        try {
            if (outputStream != null) {
                outputStream.close();
            }
            int responseCode = urlConnection.getResponseCode();
            BufferedReader rd = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
            ret = readAll(rd);
        } catch(IOException e) {
            e.printStackTrace();
            return "IOException";
        
        } finally {
            if (urlConnection != null) {
                urlConnection.disconnect();
            }         
        }
        return ret;
    }
}

Laden Sie es einfach wie bisher mit "gradle build" hoch und fertig!

Betriebszustand

Bisher haben wir etwas, das tatsächlich funktioniert. Aber es gibt immer noch Fallstricke. Dies liegt daran, dass die Zeitüberschreitung nur 3 Sekunden beträgt. Wenn Sie also die Zeit zum Starten der Lambda-Funktion angeben, tritt eine unerwartet schnelle Zeitüberschreitung auf!

Erfolgsgeschichte

Es funktioniert wie erwartet ohne Zeitüberschreitung. samplebot.gif

Fehlerbeispiel

Dies ist das Ergebnis einer Verschiebung nach einer Weile. Die Timeout-Zeit ist abgelaufen, wahrscheinlich weil die Lambda-Funktion erneut gestartet werden muss. Da ** slack es als Fehler beurteilte und das Ereignis mehrmals erneut sendete **, wurde die Lambda-Funktion mehrmals aufgerufen und mehrmals veröffentlicht. samplebot2.gif

Lösungen

Bisher ist es lange her, daher werde ich im nächsten Artikel erklären, wie dies gelöst werden kann. Bitte sehen Sie das auch [AWS Lambda] Verhindert, dass Slack Bot wiederholt mit Zeitüberschreitungen reagiert

Recommended Posts

Erstellen Sie einen SlackBot mit AWS Lambda & API Gateway in Java
Implementieren Sie API Gateway Lambda Authorizer in Java Lambda
Erstellen Sie eine CSR mit erweiterten Informationen in Java
Ich kann in IntelliJ keine Java-Klasse mit einem bestimmten Namen erstellen
Erstellen Sie ein periodisches Programm mit Ruby x AWS Lambda x CloudWatch-Ereignissen
AWS Lambda (Lambda) Teil 1 mit Java startet jetzt
Erstellen Sie eine TODO-App in Java 7 Create Header
Teilen Sie eine Zeichenfolge in Java mit ". (Dot)"
Behandeln Sie große JSON mit Java Lambda
Mit [AWS] CodeStar können Sie ein Spring (Java) -Projekt erstellen, das auf Lambda in nur 3 Minuten ausgeführt wird! !!
Ich habe eine Lambda-Funktion in Java geschrieben und mit SAM bereitgestellt
Ich möchte für jedes Array mit Lambda-Ausdruck in Java
Interagieren Sie mit der LINE Message API mit Lambda (Java)
Lesen Sie eine Zeichenfolge in einer PDF-Datei mit Java
Erstellen Sie mit Java + MySQL ein einfaches Bulletin Board
[Windows] [IntelliJ] [Java] [Tomcat] Erstellen Sie mit IntelliJ eine Umgebung für Tomcat 9
Lassen Sie uns mit Javas Timer einen zeitgesteuerten Prozess erstellen! !!
[Java] Erstellen Sie so etwas wie eine Produktsuch-API
Versuchen Sie, ein Bulletin Board in Java zu erstellen
Verwendung des Java-Frameworks mit AWS Lambda! ??
[Java] Erstellen Sie eine Sammlung mit nur einem Element
Lassen Sie uns mit Java ein supereinfaches Webframework erstellen
Verwendung der Java-API mit Lambda-Ausdrücken
Erstellen Sie einen Web-API-Server mit Spring Boot
Erstellen wir eine Taschenrechner-App mit Java ~ Erstellen Sie einen Anzeigebereich im Fenster
Überprüfen Sie das ID-Token eines von AWS Cognito in Java authentifizierten Benutzers
Zabbix API in Java
Erstellen Sie JSON in Java
Senden Sie einen Job an AWS Batch mit Java (Eclipse)
So stellen Sie Java mit Serverless Framework für AWS Lambda bereit
[Anfänger] Erstellen Sie ein wettbewerbsfähiges Spiel mit grundlegenden Java-Kenntnissen
Ich habe versucht, eine Clova-Fähigkeit in Java zu erstellen
So erstellen Sie einen Daten-URI (base64) in Java
Implementieren Sie Singleton mit Enum schnell in Java
[Hinweis] Erstellen Sie mit Docker eine Java-Umgebung von Grund auf neu
Ausgabe true mit if (a == 1 && a == 2 && a == 3) in Java (Invisible Identifier)
Schreiben wir eine Lambda-Funktion, die Amazon API Gateway in die Spring Cloud-Funktion integriert.
Erstellen wir eine TODO-Anwendung mit Java 11-Ausnahmebehandlung, wenn Sie mit einer nicht vorhandenen ID auf TODO zugreifen
Verwenden Sie Lambda-Ebenen mit Java
Ich habe versucht, mit Chocolatey eine Java8-Entwicklungsumgebung zu erstellen
Erstellen Sie eine XML-RPC-API mit Wicket
Veröffentlichen Sie regelmäßig Bild-Tweets auf Twitter mit AWS Lambda + Java
Protokollaggregation und -analyse (Arbeiten mit AWS Athena in Java)
Behandeln Sie Ausnahmen kühl mit Java 8-Lambda-Ausdrücken und der Stream-API
Java Stream API in 5 Minuten
[Java] Erstellen Sie eine temporäre Datei
Erstellen Sie einen Spielplatz mit Xcode 12
Erstellen Sie Azure-Funktionen in Java
Erstellen Sie eine Methode, um den Steuersatz in Java zurückzugeben
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben
Erstellen Sie AWS Lambda mit Quarkus
Generieren Sie AWS Signature V4 in Java und fordern Sie die API an
Erstellen Sie einen einfachen Webserver mit der Java-Standardbibliothek com.sun.net.httpserver
Lassen Sie uns eine TODO-App in Java 4 erstellen. Implementierung der Buchungsfunktion