Definisci il gestore di funzioni Lambda in Java - AWS Lambda

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Definisci il gestore di funzioni Lambda in Java

Il gestore di funzioni Lambda è il metodo nel codice della funzione che elabora gli eventi. Quando viene richiamata la funzione, Lambda esegue il metodo del gestore. La funzione viene eseguita fino a quando il gestore non restituisce una risposta, termina o scade.

Il GitHub repository di questa guida fornisce applicazioni di easy-to-deploy esempio che illustrano una varietà di tipi di gestori. Per informazioni dettagliate, consulta la parte finale di questo argomento.

Gestore di esempio: runtime di Java 17

Nell'esempio seguente di Java 17, una classe denominata HandlerIntegerJava17 definisce un metodo del gestore denominato handleRequest. Il metodo del gestore accetta i seguenti input:

  • Un IntegerRecord, che è un record Java personalizzato che rappresenta i dati degli eventi. In questo esempio, definiamo IntegerRecord come segue:

    record IntegerRecord(int x, int y, String message) { }
  • Un oggetto di contesto, che fornisce i metodi e le proprietà che forniscono le informazioni sull'invocazione, sulla funzione e sull'ambiente di esecuzione.

Supponiamo di voler scrivere una funzione che registri il message dall'IntegerRecord di input e restituisca la somma di x e y. Di seguito è riportato il codice della funzione:

Esempio HandlerIntegerJava17.java
package example; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogger; import com.amazonaws.services.lambda.runtime.RequestHandler; // Handler value: example.HandlerInteger public class HandlerIntegerJava17 implements RequestHandler<IntegerRecord, Integer>{ @Override /* * Takes in an InputRecord, which contains two integers and a String. * Logs the String, then returns the sum of the two Integers. */ public Integer handleRequest(IntegerRecord event, Context context) { LambdaLogger logger = context.getLogger(); logger.log("String found: " + event.message()); return event.x() + event.y(); } } record IntegerRecord(int x, int y, String message) { }

Specifica quale metodo Lambda deve richiamare impostando il parametro del gestore sulla configurazione della funzione. È possibile specificare il gestore nei seguenti formati:

  • package.Class::method: formato completo . Ad esempio: example.Handler::handleRequest.

  • package.Class: formato abbreviato per le classi che implementano un'interfaccia del gestore. Ad esempio: example.Handler.

Quando Lambda richiama il gestore, il runtime Lambda riceve un evento come stringa in formato JSON e lo converte in un oggetto. Nell'esempio precedente, un evento di esempio potrebbe essere simile al seguente:

Esempio event.json
{ "x": 1, "y": 20, "message": "Hello World!" }

Puoi salvare questo file e testare la tua funzione localmente con il seguente comando AWS Command Line Interface (CLI):

aws lambda invoke --function-name function_name --payload file://event.json out.json

Gestore di esempio: runtime di Java 11 e versioni precedenti

Lambda supporta i record nei runtime di Java 17 e successivi. In tutti i runtime di Java, è possibile utilizzare una classe per rappresentare i dati degli eventi. L'esempio seguente utilizza un elenco di numeri interi e un oggetto di contesto come input e restituisce la somma di tutti i numeri interi nell'elenco.

Esempio Handler.java

Nell'esempio seguente, una classe denominata Handler definisce un metodo del gestore denominato handleRequest. Il metodo del gestore accetta un oggetto evento e contesto come input e restituisce una stringa.

Esempio HandlerList.java
package example; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogger; import com.amazonaws.services.lambda.runtime.RequestHandler; import java.util.List; // Handler value: example.HandlerList public class HandlerList implements RequestHandler<List<Integer>, Integer>{ @Override /* * Takes a list of Integers and returns its sum. */ public Integer handleRequest(List<Integer> event, Context context) { LambdaLogger logger = context.getLogger(); logger.log("EVENT TYPE: " + event.getClass().toString()); return event.stream().mapToInt(Integer::intValue).sum(); } }

Per altri esempi, consulta la pagina Codice del gestore di esempio.

Codice di inizializzazione

Lambda esegue il codice statico e il costruttore della classe durante la fase di inizializzazione prima di richiamare la funzione per la prima volta. Le risorse create durante l'inizializzazione restano in memoria tra un'invocazione e l'altra e possono essere riutilizzate dal gestore migliaia di volte. È possibile aggiungere il codice di inizializzazione al di fuori del metodo del gestore per risparmiare tempo di calcolo e riutilizzare le risorse tra più invocazioni.

Nell'esempio seguente, il codice di inizializzazione del client non rientra nel metodo del gestore principale. Il runtime inizializza il client prima che la funzione esegua il suo primo evento. Gli eventi successivi sono molto più veloci perché Lambda non ha bisogno di inizializzare nuovamente il client.

Esempio Handler.java
package example; import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.LambdaLogger; import com.amazonaws.services.lambda.runtime.RequestHandler; import java.util.Map; import software.amazon.awssdk.services.lambda.LambdaClient; import software.amazon.awssdk.services.lambda.model.GetAccountSettingsResponse; import software.amazon.awssdk.services.lambda.model.LambdaException; // Handler value: example.Handler public class Handler implements RequestHandler<Map<String,String>, String> { private static final LambdaClient lambdaClient = LambdaClient.builder().build(); @Override public String handleRequest(Map<String,String> event, Context context) { LambdaLogger logger = context.getLogger(); logger.log("Handler invoked"); GetAccountSettingsResponse response = null; try { response = lambdaClient.getAccountSettings(); } catch(LambdaException e) { logger.log(e.getMessage()); } return response != null ? "Total code size for your account is " + response.accountLimit().totalCodeSize() + " bytes" : "Error"; } }

Scelta dei tipi di input e di output

Specificare il tipo di oggetto a cui l'evento si mappa nella firma del metodo del gestore. Nell'esempio precedente, il runtime di Java deserializza l'evento in un tipo che implementa l'interfaccia Map<String,String>. tring-to-string Le mappe S funzionano per eventi flat come i seguenti:

Esempio Event.json – Dati meteo
{ "temperatureK": 281, "windKmh": -3, "humidityPct": 0.55, "pressureHPa": 1020 }

Tuttavia, il valore di ogni campo deve essere una stringa o un numero. Se l'evento include un campo con un oggetto come valore, il runtime non può deserializzarlo e restituisce un errore.

Scegliere un tipo di input che funzioni con i dati degli eventi elaborati dalla funzione. È possibile utilizzare un tipo di base, un tipo generico o un tipo ben definito.

Tipi di input
  • Integer, Long, Double e così via. – L' evento è un numero senza formattazione aggiuntiva, ad esempio 3.5. Il runtime converte il valore in un oggetto del tipo specificato.

  • String: l'evento è una stringa JSON, incluse le virgolette, ad esempio "My string.". Il runtime converte il valore (senza virgolette) in un oggetto String.

  • Type, Map<String,Type> e così via. – L'evento è un oggetto JSON. Il runtime lo deserializza in un oggetto del tipo o dell'interfaccia specificati.

  • List<Integer>, List<String>, List<Object> e così via. – L'evento è un array JSON. Il runtime lo deserializza in un oggetto del tipo o dell'interfaccia specificati.

  • InputStream: l'evento è un tipo qualsiasi di JSON. Il runtime passa un flusso di byte del documento al gestore senza modifiche. Si deserializza l'output di input e scrittura in un flusso di output.

  • Tipo di libreria: per gli eventi inviati dai AWS servizi, usa i tipi nella libreria aws-lambda-java-events.

Se si definisce il proprio tipo di input, dovrebbe essere un vecchio oggetto Java (POJO) deserializzabile e mutabile, con un costruttore predefinito e proprietà per ogni campo nell'evento. Le chiavi nell'evento che non si mappano a una proprietà e le proprietà che non sono incluse nell'evento vengono eliminate senza errori.

Il tipo di output può essere un oggetto o void. Il runtime serializza i valori restituiti in testo. Se l'output è un oggetto con campi, il runtime lo serializza in un documento JSON. Se è un tipo che esegue il wrapping di un valore primitivo, il runtime restituisce una rappresentazione testuale di tale valore.

Interfacce del gestore

La libreria aws-lambda-java-core definisce due interfacce per i metodi del gestore. Utilizzare le interfacce fornite per semplificare la configurazione del gestore e convalidare la firma del metodo del gestore in fase di compilazione.

L'interfaccia RequestHandler è un tipo generico che accetta due parametri: il tipo di input e il tipo di output. Entrambi i tipi devono essere oggetti. Quando si utilizza questa interfaccia, il runtime Java deserializza l'evento in un oggetto con il tipo di input e serializza l'output in testo. Utilizzare questa interfaccia quando la serializzazione integrata funziona con i tipi di input e output.

Esempio Handler.java – Interfaccia del gestore
// Handler value: example.Handler public class Handler implements RequestHandler<Map<String,String>, String>{ @Override public String handleRequest(Map<String,String> event, Context context)

Per utilizzare la propria serializzazione, implementare l'interfaccia RequestStreamHandler. Con questa interfaccia, Lambda passa al gestore un flusso di input e un flusso di output. Il gestore legge i byte dal flusso di input, scrive nel flusso di output e restituisce il valore void.

Nell'esempio seguente vengono utilizzati tipi di lettore e di writer memorizzati per utilizzare i flussi di input e output.

Esempio HandlerStream.java
import com.amazonaws.services.lambda.runtime.Context import com.amazonaws.services.lambda.runtime.LambdaLogger import com.amazonaws.services.lambda.runtime.RequestStreamHandler ... // Handler value: example.HandlerStream public class HandlerStream implements RequestStreamHandler { @Override /* * Takes an InputStream and an OutputStream. Reads from the InputStream, * and copies all characters to the OutputStream. */ public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { LambdaLogger logger = context.getLogger(); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("US-ASCII"))); PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream, Charset.forName("US-ASCII")))); int nextChar; try { while ((nextChar = reader.read()) != -1) { outputStream.write(nextChar); } } catch (IOException e) { e.printStackTrace(); } finally { reader.close(); String finalString = writer.toString(); logger.log("Final string result: " + finalString); writer.close(); } } }

Codice di esempio del gestore

L' GitHub archivio di questa guida include applicazioni di esempio che dimostrano l'uso di vari tipi di gestori e interfacce. Ogni applicazione di esempio include script per facilitare la distribuzione e la pulizia, un AWS SAM modello e risorse di supporto.

Applicazioni Lambda di esempio in Java
  • java17-examples: una funzione Java che dimostra come utilizzare un record Java per rappresentare un oggetto di dati dell'evento di input.

  • java-basic: una raccolta di funzioni Java minimali con unit test e configurazione della registrazione dei log delle variabili.

  • java-events: una raccolta di funzioni Java che contengono codice skeleton per la gestione degli eventi di vari servizi, ad esempio Gateway Amazon API, Amazon SQS e Amazon Kinesis. Queste funzioni utilizzano la versione più recente della libreria aws-lambda-java-events (3.0.0 e versioni successive). Questi esempi non richiedono l' AWS SDK come dipendenza.

  • s3-java – Una funzione Java che elabora gli eventi di notifica da Amazon S3 e utilizza la Java Class Library (JCL) per creare anteprime dai file di immagine caricati.

  • Utilizza API Gateway per richiamare una funzione Lambda: una funzione Java che esegue la scansione di una tabella Amazon DynamoDB che contiene informazioni sui dipendenti. Quindi utilizza Amazon Simple Notification Service per inviare un messaggio di testo ai dipendenti per festeggiare i loro anniversari di lavoro. Questo esempio usa API Gateway per richiamare la funzione.

Le s3-java applicazioni java-events and accettano un evento AWS di servizio come input e restituiscono una stringa. L'applicazione java-basic include vari tipi di gestori:

Per testare diversi tipi di gestore, è sufficiente modificare il valore del gestore nel AWS SAM modello. Per istruzioni dettagliate, consultare il file readme dell'applicazione di esempio.