Java-Entwicklerhandbuch für Azure FunctionsAzure Functions Java developer guide

Die Azure Functions-Runtime unterstützt Java SE 8 LTS (zulu8.31.0.2-jre8.0.181-win_x64).The Azure Functions runtime supports Java SE 8 LTS (zulu8.31.0.2-jre8.0.181-win_x64).

Dieser Leitfaden enthält Informationen zu den Feinheiten beim Schreiben von Azure Functions mit Java.This guide contains information about the intricacies of writing Azure Functions with Java.

Eine Java-Funktion ist eine public-Methode, die mit Anmerkungen der Form @FunctionName versehen ist.A Java function is a public method decorated with annotation @FunctionName. Diese Methode definiert die Eingabe für eine Java-Funktion und muss in jedem Paket eindeutig sein.This method defines the entry for a java function and must be unique in a given package.

In diesem Artikel wird davon ausgegangen, dass Sie bereits die Entwicklerreferenz zu Azure Functionsgelesen haben.This article assumes that you have already read the Azure Functions developer reference. Es empfiehlt sich zudem, die Schnellstartanleitung zu Functions zu lesen, um Ihre erste Funktion mit Visual Studio Code oder Maven zu erstellen.You should also complete the Functions quickstart to create your first function, using Visual Studio Code or using maven.

ProgrammiermodellProgramming model

Die Konzepte von Triggern und Bindungen sind für Azure Functions von grundlegender Bedeutung.The concepts of triggers and bindings are fundamental to Azure Functions. Trigger starten die Ausführung Ihres Codes.Triggers start the execution of your code. Bindungen bieten Ihnen eine Möglichkeit, Daten an eine Funktion zu übergeben und von einer Funktion zurückgeben zu lassen, ohne benutzerdefinierten Datenzugriffscode schreiben zu müssen.Bindings give you a way to pass data to and return data from a function, without having to write custom data access code.

OrdnerstrukturFolder structure

Im Folgenden wird die Ordnerstruktur eines Azure Functions-Java-Projekts gezeigt:Here is the folder structure of an Azure Function Java project:

FunctionsProject
 | - src
 | | - main
 | | | - java
 | | | | - FunctionApp
 | | | | | - MyFirstFunction.java
 | | | | | - MySecondFunction.java
 | - target
 | | - azure-functions
 | | | - FunctionApp
 | | | | - FunctionApp.jar
 | | | | - host.json
 | | | | - MyFirstFunction
 | | | | | - function.json
 | | | | - MySecondFunction
 | | | | | - function.json
 | | | | - bin
 | | | | - lib
 | - pom.xml

Sie können die freigegebene Datei host.json zum Konfigurieren der Funktions-App verwenden.There's a shared host.json file that can be used to configure the function app. Jede Funktion verfügt über eine eigene Codedatei (JAVA-Datei) sowie über eine eigene Bindungskonfigurationsdatei („function.json“).Each function has its own code file (.java) and binding configuration file (function.json).

Sie können mehr als eine Funktion in ein Projekt einfügen.You can put more than one function in a project. Vermeiden Sie es, Ihre Funktionen in separaten JAR-Dateien hinzuzufügen.Avoid putting your functions into separate jars. Die Funktions-App im Zielverzeichnis wird in Ihrer Funktions-App in Azure bereitgestellt.The FunctionApp in the target directory is what gets deployed to your function app in Azure.

Trigger und AnmerkungenTriggers and annotations

Azure-Funktionen werden durch einen Trigger, z.B. eine HTTP-Anforderung, einen Timer oder ein Datenupdate, aufgerufen.Azure functions are invoked by a trigger, such as an HTTP request, a timer, or an update to data. Ihre Funktion muss diesen Trigger und alle weiteren Eingaben verarbeiten, um mindestens eine Ausgabe zu erstellen.Your function needs to process that trigger and any other inputs to produce one or more outputs.

Verwenden Sie die Java-Anmerkungen im Paket com.microsoft.azure.functions.annotation.*, um Eingaben und Ausgaben an Ihre Methoden zu binden.Use the Java annotations included in the com.microsoft.azure.functions.annotation.* package to bind input and outputs to your methods. Weitere Informationen finden Sie unter Java-Referenzdokumentation.For more information, see Java reference docs.

Wichtig

Sie müssen ein Azure Storage-Konto in local.settings.json konfigurieren, um Trigger für Azure Storage Blob, Azure Queue Storage oder Azure Table Storage lokal auszuführen.You must configure an Azure Storage account in your local.settings.json to run Azure Storage Blob, Queue, or Table triggers locally.

Beispiel:Example:

public class Function {
    public String echo(@HttpTrigger(name = "req", 
      methods = {"post"},  authLevel = AuthorizationLevel.ANONYMOUS) 
        String req, ExecutionContext context) {
        return String.format(req);
    }
}

Hier wird die entsprechende function.json gezeigt, die durch azure-functions-maven-plugin generiert wurde:here is the generated corresponding function.json by the azure-functions-maven-plugin:

{
  "scriptFile": "azure-functions-example.jar",
  "entryPoint": "com.example.Function.echo",
  "bindings": [
    {
      "type": "httpTrigger",
      "name": "req",
      "direction": "in",
      "authLevel": "anonymous",
      "methods": [ "post" ]
    },
    {
      "type": "http",
      "name": "$return",
      "direction": "out"
    }
  ]
}

Verfügbarkeit und Unterstützung der JDK-RuntimeJDK runtime availability and support

Laden Sie die Azul Zulu Enterprise for Azure Java 8-JDKs von Azul Systems für die lokale Entwicklung von Java-Funktions-Apps herunter, und verwenden Sie sie.Download and use the Azul Zulu Enterprise for Azure Java 8 JDKs from Azul Systems for local development of Java function apps. Azure Functions verwendet die Azul Java 8 JDK-Runtime, wenn Sie Ihre Funktions-Apps in der Cloud bereitstellen.Azure Functions uses the Azul Java 8 JDK runtime when you deploy your function apps to the cloud.

Azure-Support bei Problemen mit den JDKs und Funktions-Apps steht mit einem qualifizierten Supportplan zur Verfügung.Azure support for issues with the JDKs and Function apps is available with a qualified support plan.

Anpassen der JVMCustomize JVM

Mit Functions können Sie die Java Virtual Machine (JVM) anpassen, mit der Sie Ihre Java-Funktionen ausführen.Functions lets you customize the Java virtual machine (JVM) used to execute your Java functions. Die folgenden JVM-Optionen werden standardmäßig verwendet:The following JVM options are used by default:

  • -XX:+TieredCompilation
  • -XX:TieredStopAtLevel=1
  • -noverify
  • -Djava.net.preferIPv4Stack=true
  • -jar

Sie können weitere Argumente in einer App-Einstellung namens JAVA_OPTS angeben.You can provide additional arguments in an app setting named JAVA_OPTS. Sie können auf eine der folgenden Arten App-Einstellungen zu Ihrer Funktions-App hinzufügen, die in Azure bereitgestellt wird:You can add app settings to your function app deployed to Azure in one of these ways:

Azure-PortalAzure portal

Verwenden Sie im Azur-Portal die Registerkarte Anwendungseinstellungen, um die Einstellung JAVA_OPTS hinzuzufügen.In the Azure portal, use the Application Settings tab to add the JAVA_OPTS setting.

Azure-BefehlszeilenschnittstelleAzure CLI

Mit dem Befehl az functionapp config appsettings set können Sie JAVA_OPTS wie im folgenden Beispiel einstellen:The az functionapp config appsettings set command can be used to set JAVA_OPTS, as in the following example:

```azurecli-interactive
az functionapp config appsettings set --name <APP_NAME> \
--resource-group <RESOURCE_GROUP> \
--settings "JAVA_OPTS=-Djava.awt.headless=true"
```

In diesem Beispiel wird der monitorlose Modus aktiviert.This example enables headless mode. Ersetzen Sie <APP_NAME> durch den Namen Ihrer Funktions-App und <RESOURCE_GROUP> durch die Ressourcengruppe.Replace <APP_NAME> with the name of your function app and <RESOURCE_GROUP> with the resource group.

Warnung

Bei Verwendung in einem Verbrauchsplan müssen Sie die Einstellung WEBSITE_USE_PLACEHOLDER mit dem Wert 0 hinzufügen.When running in a Consumption plan, you must add the WEBSITE_USE_PLACEHOLDER setting with a value of 0.
Diese Einstellung erhöht die Kaltstartzeiten für Java-Funktionen.This setting does increase the cold start times for Java functions.

DrittanbieterbibliothekenThird-party libraries

Azure Functions unterstützt die Verwendung von Drittanbieterbibliotheken.Azure Functions supports the use of third-party libraries. Standardmäßig werden alle in der Projektdatei pom.xml angegebenen Abhängigkeiten automatisch während des Ziels von mvn package gebündelt.By default, all dependencies specified in your project pom.xml file will be automatically bundled during the mvn package goal. Bibliotheken, die nicht in der Datei pom.xml als Abhängigkeiten angegeben sind, platzieren Sie in einem lib-Verzeichnis im Stammverzeichnis der Funktion.For libraries not specified as dependencies in the pom.xml file, place them in a lib directory in the function's root directory. Abhängigkeiten im Verzeichnis lib werden dem Systemklassen-Ladeprogramm zur Laufzeit hinzugefügt.Dependencies placed in the lib directory will be added to the system class loader at runtime.

Die Abhängigkeit com.microsoft.azure.functions:azure-functions-java-library wird standardmäßig im Klassenpfad bereitgestellt und muss nicht in das Verzeichnis lib eingeschlossen werden.The com.microsoft.azure.functions:azure-functions-java-library dependency is provided on the classpath by default, and does not need to be included in the lib directory. Darüber hinaus werden die hier aufgelisteten Abhängigkeiten durch azure-functions-java-worker dem Klassenpfad hinzugefügt.Also, dependencies listed here are added to the classpath by azure-functions-java-worker.

Unterstützung von DatentypenData type support

Zum Binden an Eingabe-/Ausgabebindungen können Sie POJOs (Plain Old Java Objects), in azure-functions-java-library definierte Typen oder primitive Datentypen wie z.B. „String“ oder „Integer“ verwenden.You can use Plain old Java objects (POJOs), types defined in azure-functions-java-library or primitive dataTypes such as String, Integer to bind to input/output bindings.

Plain Old Java Objects (POJOs, „ganz normale“ Java-Objekte)Plain old Java objects (POJOs)

Zum Konvertieren von Eingabedaten in POJO verwendet azure-functions-java-worker die gson-Bibliothek.For converting input data to POJO, azure-functions-java-worker uses gson library. Als Eingabe für Funktionen verwendete POJO-Typen müssen public sein.POJO types used as inputs to functions should be public.

BinärdatenBinary data

Binden Sie binäre Eingaben oder Ausgaben an byte[], indem Sie das Feld dataType in der Datei „function.json“ auf binary festlegen:Bind binary inputs or outputs to byte[] by setting the dataType field in your function.json to binary:

   @FunctionName("BlobTrigger")
    @StorageAccount("AzureWebJobsStorage")
     public void blobTrigger(
        @BlobTrigger(name = "content", path = "myblob/{fileName}", dataType = "binary") byte[] content,
        @BindingName("fileName") String fileName,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java Blob trigger function processed a blob.\n Name: " + fileName + "\n Size: " + content.length + " Bytes");
    }

Verwenden Sie Optional<T>, wenn NULL-Werte erwartet werden.Use Optional<T> for if null values are expected

BindungenBindings

Eingabe- und Ausgabebindungen bieten eine deklarative Möglichkeit, aus Code heraus Verbindungen mit Daten herzustellen.Input and output bindings provide a declarative way to connect to data from within your code. Eine Funktion kann mehrere Eingabe- und Ausgabebindungen aufweisen.A function can have multiple input and output bindings.

Beispiel für eine EingabebindungExample Input binding

package com.example;

import com.microsoft.azure.functions.annotation.*;

public class Function {
    @FunctionName("echo")
    public static String echo(
        @HttpTrigger(name = "req", methods = { "put" }, authLevel = AuthorizationLevel.ANONYMOUS, route = "items/{id}") String inputReq,
        @TableInput(name = "item", tableName = "items", partitionKey = "Example", rowKey = "{id}", connection = "AzureWebJobsStorage") TestInputData inputData
        @TableOutput(name = "myOutputTable", tableName = "Person", connection = "AzureWebJobsStorage") OutputBinding<Person> testOutputData,
    ) {
        testOutputData.setValue(new Person(httpbody + "Partition", httpbody + "Row", httpbody + "Name"));
        return "Hello, " + inputReq + " and " + inputData.getKey() + ".";
    }

    public static class TestInputData {
        public String getKey() { return this.RowKey; }
        private String RowKey;
    }
    public static class Person {
        public String PartitionKey;
        public String RowKey;
        public String Name;

        public Person(String p, String r, String n) {
            this.PartitionKey = p;
            this.RowKey = r;
            this.Name = n;
        }
    }
}

Diese Funktion wird mit einer HTTP-Anforderung aufgerufen.This function is invoked with an HTTP request.

  • Die Nutzlast der HTTP-Anforderung wird dem Argument inputReq als String übergeben.HTTP request payload is passed as a String for the argument inputReq
  • Ein Eintrag wird aus Azure Table Storage abgerufen und dem Argument inputData als TestInputData übergeben.One entry is retrieved from the Azure Table Storage and is passed as TestInputData to the argument inputData.

Sie können eine Bindung mit String[], POJO[], List<String> oder List<POJO> herstellen, um eine Reihe von Eingaben zu erhalten.To receive a batch of inputs, you can bind to String[], POJO[], List<String>, or List<POJO>.

@FunctionName("ProcessIotMessages")
    public void processIotMessages(
        @EventHubTrigger(name = "message", eventHubName = "%AzureWebJobsEventHubPath%", connection = "AzureWebJobsEventHubSender", cardinality = Cardinality.MANY) List<TestEventData> messages,
        final ExecutionContext context)
    {
        context.getLogger().info("Java Event Hub trigger received messages. Batch size: " + messages.size());
    }
    
    public class TestEventData {
    public String id;
}

Diese Funktion wird immer dann ausgelöst, wenn im konfigurierten Event Hub neue Daten vorliegen.This function gets triggered whenever there is new data in the configured event hub. Da die cardinality auf MANY festgelegt ist, empfängt die Funktion einen Batch von Nachrichten von Event Hub.As the cardinality is set to MANY, function receives a batch of messages from event hub. EventData aus Event Hub wird für die Ausführung der Funktion in TestEventData konvertiert.EventData from event hub gets converted to TestEventData for the function execution.

Beispiel für eine AusgabebindungExample Output binding

Mit $return können Sie eine Ausgabebindung an den Rückgabewert binden.You can bind an output binding to the return value using $return

package com.example;

import com.microsoft.azure.functions.annotation.*;

public class Function {
    @FunctionName("copy")
    @StorageAccount("AzureWebJobsStorage")
    @BlobOutput(name = "$return", path = "samples-output-java/{name}")
    public static String copy(@BlobTrigger(name = "blob", path = "samples-input-java/{name}") String content) {
        return content;
    }
}

Wenn mehrere Ausgabebindungen vorhanden sind, verwenden Sie den Rückgabewert für nur eine davon.If there are multiple output bindings, use the return value for only one of them.

Um mehrere Ausgabewerte zu senden, verwenden Sie OutputBinding<T> gemäß der Definition im Paket azure-functions-java-library.To send multiple output values, use OutputBinding<T> defined in the azure-functions-java-library package.

@FunctionName("QueueOutputPOJOList")
    public HttpResponseMessage QueueOutputPOJOList(@HttpTrigger(name = "req", methods = { HttpMethod.GET,
            HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            @QueueOutput(name = "itemsOut", queueName = "test-output-java-pojo", connection = "AzureWebJobsStorage") OutputBinding<List<TestData>> itemsOut, 
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");
       
        String query = request.getQueryParameters().get("queueMessageId");
        String queueMessageId = request.getBody().orElse(query);
        itemsOut.setValue(new ArrayList<TestData>());
        if (queueMessageId != null) {
            TestData testData1 = new TestData();
            testData1.id = "msg1"+queueMessageId;
            TestData testData2 = new TestData();
            testData2.id = "msg2"+queueMessageId;

            itemsOut.getValue().add(testData1);
            itemsOut.getValue().add(testData2);

            return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + queueMessageId).build();
        } else {
            return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Did not find expected items in CosmosDB input list").build();
        }
    }

     public static class TestData {
        public String id;
    }

Diese Funktion wird über HttpRequest aufgerufen und schreibt mehrere Werte in die Azure Queue.This function is invoked on an HttpRequest and writes multiple values to the Azure Queue.

HttpRequestMessage und HttpResponseMessageHttpRequestMessage and HttpResponseMessage

Die in azure-functions-java-library definierten HttpRequestMessage- und HttpResponseMessage-Typen sind Hilfstypen, die mit HttpTrigger-Funktionen verwendet werden.HttpRequestMessage and HttpResponseMessage types are defined in azure-functions-java-library are helper types to work with HttpTrigger functions

Spezialisierter TypSpecialized Type ZielTarget Typische VerwendungTypical Usage
HttpRequestMessage<T> HTTP-TriggerHTTP Trigger Get-Methode, Header oder AbfragenGet method, headers, or queries
HttpResponseMessage HTTP-AusgabebindungHTTP Output Binding Anderer Rückgabestatus als 200Return status other than 200

MetadatenMetadata

Einige Trigger senden Triggermetadaten zusammen mit den Eingabedaten.Few triggers send trigger metadata along with input data. Sie können die Anmerkung @BindingName für die Bindung an Triggermetadaten verwenden.You can use annotation @BindingName to bind to trigger metadata

package com.example;

import java.util.Optional;
import com.microsoft.azure.functions.annotation.*;


public class Function {
    @FunctionName("metadata")
    public static String metadata(
        @HttpTrigger(name = "req", methods = { "get", "post" }, authLevel = AuthorizationLevel.ANONYMOUS) Optional<String> body,
        @BindingName("name") String queryValue
    ) {
        return body.orElse(queryValue);
    }
}

Im obigen Beispiel ist queryValue an den Abfragezeichenfolgen-Parameter name in der HTTP-Anforderungs-URL http://{example.host}/api/metadata?name=test gebunden.In the example above, the queryValue is bound to query string parameter name in the Http request URL http://{example.host}/api/metadata?name=test. Es folgt ein weiteres Beispiel für die Bindung an die Id aus den Metadaten des Warteschlangentriggers.Following is another example to binding to Id from queue trigger metadata

 @FunctionName("QueueTriggerMetadata")
    public void QueueTriggerMetadata(
        @QueueTrigger(name = "message", queueName = "test-input-java-metadata", connection = "AzureWebJobsStorage") String message,@BindingName("Id") String metadataId,
        @QueueOutput(name = "output", queueName = "test-output-java-metadata", connection = "AzureWebJobsStorage") OutputBinding<TestData> output,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java Queue trigger function processed a message: " + message + " with metadaId:" + metadataId );
        TestData testData = new TestData();
        testData.id = metadataId;
        output.setValue(testData);
    }

Hinweis

Der in der Anmerkung angegebene Name muss der Metadateneigenschaft entsprechen.Name provided in the annotation needs to match the metadata property

AusführungskontextExecution context

Der in der azure-functions-java-library definierte ExecutionContext enthält Hilfsmethoden für die Kommunikation mit der Funktionsruntime.ExecutionContext defined in the azure-functions-java-library contains helper methods to communicate with the functions runtime.

ProtokollierungstoolLogger

Verwenden Sie den im ExecutionContext definierten getLogger zum Schreiben von Protokollen aus Funktionscode.Use getLogger defined in ExecutionContext to write logs from function code.

Beispiel:Example:


import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;

public class Function {
    public String echo(@HttpTrigger(name = "req", methods = {"post"}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) {
        if (req.isEmpty()) {
            context.getLogger().warning("Empty request body received by function " + context.getFunctionName() + " with invocation " + context.getInvocationId());
        }
        return String.format(req);
    }
}

Anzeigen von Protokollen und AblaufverfolgungView logs and trace

Mit der Azure CLI können Sie die Java-Protokollierung von stdout und stderr sowie andere Anwendungsprotokolle streamen.You can use the Azure CLI to stream Java stdout and stderr logging as well as other application logging.

Konfigurieren Sie Ihre Funktionsanwendung, um die Anwendungsprotokollierung mithilfe der Azure CLI zu schreiben:Configure your Function application to write application logging using the Azure CLI:

az webapp log config --name functionname --resource-group myResourceGroup --application-logging true

Zum Streaming der Protokollausgabe Ihrer Funktions-App mithilfe der Azure CLI öffnen Sie eine neue Eingabeaufforderungs-, Bash- oder Terminalsitzung und geben den folgenden Befehl ein:To stream logging output for your Function app using the Azure CLI, open a new command prompt, Bash, or Terminal session and enter the following command:

az webapp log tail --name webappname --resource-group myResourceGroup

Der Befehl az webapp log tail ermöglicht das Filtern der Ausgabe mithilfe der Option --provider.The az webapp log tail command has options to filter output using the --provider option.

Zum Herunterladen der Protokolldateien mit der Azure CLI als einzelne ZIP-Datei öffnen Sie eine neue Eingabeaufforderungs-, Bash- oder Terminalsitzung und geben den folgenden Befehl ein:To download the log files as a single ZIP file using the Azure CLI, open a new command prompt, Bash, or Terminal session and enter the following command:

az webapp log download --resource-group resourcegroupname --name functionappname

Die Dateisystemprotokollierung muss im Azure-Portal oder in der Azure CLI aktiviert sein, bevor Sie diesen Befehl ausführen können.You must have enabled file system logging in the Azure portal or Azure CLI before running this command.

UmgebungsvariablenEnvironment variables

In Functions werden App-Einstellungen, z.B. Dienstverbindungszeichenfolgen, während der Ausführung als Umgebungsvariablen verfügbar gemacht.In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. Sie können über System.getenv("AzureWebJobsStorage") auf diese Einstellungen zugreifen.You can access these settings using, System.getenv("AzureWebJobsStorage")

Beispiel:Example:

Hinzufügen von AppSetting mit dem Namen „testAppSetting“ und dem Wert „testAppSettingValue“Add AppSetting with name testAppSetting and value testAppSettingValue


public class Function {
    public String echo(@HttpTrigger(name = "req", methods = {"post"}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) {
        context.getLogger().info("testAppSetting "+ System.getenv("testAppSettingValue"));
        return String.format(req);
    }
}

Nächste SchritteNext steps

Weitere Informationen zur Java-Entwicklung für Azure Functions finden Sie in den folgenden Ressourcen:For more information about Azure Function Java development, see the following resources: