Azure Functions Java 開發人員指南Azure Functions Java developer guide

Azure Functions 執行時間支援JAVA SE 8 LTS (祖魯 8.31.0.2-jre 8.0.181-win_x64)The Azure Functions runtime supports Java SE 8 LTS (zulu8.31.0.2-jre8.0.181-win_x64). 本指南包含使用 JAVA 撰寫 Azure Functions 複雜性的相關資訊。This guide contains information about the intricacies of writing Azure Functions with Java.

對其他語言而言,函數應用程式可能會有一或多個函式。As it happens to other languages, a Function App may have one or more functions. JAVA 函式是public以注釋@FunctionName裝飾的方法。A Java function is a public method, decorated with the annotation @FunctionName. 這個方法會定義 JAVA 函數的專案,而且在特定封裝中必須是唯一的。This method defines the entry for a Java function, and must be unique in a particular package. 以 JAVA 撰寫的其中一個函數應用程式可能會有多個類別,其中@FunctionName有多個以標注的公用方法。One Function App written in Java may have multiple classes with multiple public methods annotated with @FunctionName.

本文假設您已經讀過 Azure Functions 開發人員參考This article assumes that you have already read the Azure Functions developer reference. 您也應該使用Visual Studio CodeMaven來完成函式快速入門,以建立您的第一個函式。You should also complete the Functions quickstart to create your first function, by using Visual Studio Code or Maven.

程式設計模型Programming model

觸發程序和繫結的概念是 Azure Functions 的基礎。The concepts of triggers and bindings are fundamental to Azure Functions. 觸發程序會開始執行您的程式碼。Triggers start the execution of your code. 繫結可讓您將資料傳至函式以及從函式傳回資料,而不需要撰寫自訂的資料存取程式碼。Bindings give you a way to pass data to and return data from a function, without having to write custom data access code.

專案樣板Project Scaffolding

Scaffold 以 JAVA 為基礎的 Azure Function 專案最簡單的方式是使用Apache Maven archetype。The simplest way to scaffold a Java-based Azure Function project is to use Apache Maven archetypes. 您也可以在 Visual Studio Code 和適用于 Eclipse 和 IntelliJ 的 Azure 工具組上尋找專案產生的嚮導。You can also find project generation wizards on Visual Studio Code, and the Azure Toolkits for Eclipse and IntelliJ.

目前有兩個適用于 Maven 的 Azure Functions archetype:There are currently two Azure Functions archetypes for Maven:

JAVA 原型Java Archetype

這個原型會在下列 groupId 和 artifactId 之下發行。 microsoft azure: azure 函式原型This archetype is published under the following groupId and artifactId com.microsoft.azure:azure-functions-archetype.

mvn archetype:generate \
    -DarchetypeGroupId=com.microsoft.azure \
    -DarchetypeArtifactId=azure-functions-archetype 

Kotlin 原型(預覽)Kotlin Archetype (Preview)

這個原型是以下列 groupId 和 artifactId 來發行。 microsoft azure: kotlin-原型This archetype is published under the following groupId and artifactId com.microsoft.azure:azure-functions-kotlin-archetype.

mvn archetype:generate \
    -DarchetypeGroupId=com.microsoft.azure \
    -DarchetypeArtifactId=azure-functions-kotlin-archetype

這些 archetype 的原始程式碼可以在Azure Maven Archetype GitHub 存放庫中找到。The source code of these archetypes can be found on the Azure Maven Archetypes GitHub repository.

資料夾結構Folder structure

以下是 Azure Functions JAVA 專案的資料夾結構:Here is the folder structure of an Azure Functions 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

* Kotlin 專案看起來非常類似,因為它仍然是 Maven* The Kotlin project looks very similar since it is still Maven

您可以使用共用的主機 json檔案來設定函數應用程式。You can use a shared host.json file to configure the function app. 每個函式都有自己的程式碼檔案 (.java) 和繫結設定檔 (function.json)。Each function has its own code file (.java) and binding configuration file (function.json).

您可以在專案中放入多個函式。You can put more than one function in a project. 請勿將函式放入個別的 jar。Avoid putting your functions into separate jars. 目標FunctionApp目錄中的會部署至 Azure 中的函數應用程式。The FunctionApp in the target directory is what gets deployed to your function app in Azure.

觸發程序和註解Triggers and annotations

函數是由觸發程式叫用,例如 HTTP 要求、計時器或資料的更新。Functions are invoked by a trigger, such as an HTTP request, a timer, or an update to data. 您的函式必須處理該觸發程式和其他任何輸入,以產生一或多個輸出。Your function needs to process that trigger, and any other inputs, to produce one or more outputs.

請使用 com.microsoft.azure.functions.annotation.* 套件中所包含的 Java 註釋,以將輸入和輸出繫結至方法。Use the Java annotations included in the com.microsoft.azure.functions.annotation.* package to bind input and outputs to your methods. 如需詳細資訊,請參閱JAVA 參考檔。For more information, see the Java reference docs.

重要

您必須在您的本機. 設定中設定 Azure 儲存體帳戶,以在本機執行 azure Blob 儲存體、Azure 佇列儲存體或 azure 資料表儲存體觸發程式。You must configure an Azure Storage account in your local.settings.json to run Azure Blob storage, Azure Queue storage, or Azure Table storage triggers locally.

範例:Example:

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

以下是由 azure 函function.json 式-maven-外掛程式產生的對應: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"
    }
  ]
}

JDK 執行階段可用性和支援JDK runtime availability and support

若要在本機開發 JAVA 函數應用程式,請下載並使用來自Azul 系統Azul 祖魯 Enterprise for Azure JAVA 8 jdk。For local development of Java function apps, download and use the Azul Zulu Enterprise for Azure Java 8 JDKs from Azul Systems. 當您將函數應用程式部署至雲端時,Azure Functions 使用 Azul Java 8 JDK 執行階段。Azure Functions uses the Azul Java 8 JDK runtime when you deploy your function apps to the cloud.

Jdk 和函數應用程式的相關問題Azure 支援可透過合格的支援方案取得。Azure support for issues with the JDKs and function apps is available with a qualified support plan.

自訂 JVMCustomize JVM

函式可讓您自訂用來執行 JAVA 功能的 JAVA 虛擬機器(JVM)。Functions lets you customize the Java virtual machine (JVM) used to run your Java functions. 預設會使用下列 JVM 選項The following JVM options are used by default:

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

您可以在名為JAVA_OPTS的應用程式設定中提供額外的引數。You can provide additional arguments in an app setting named JAVA_OPTS. 您可以在 Azure 入口網站或 Azure CLI 中,將應用程式設定新增至部署至 Azure 的函數應用程式。You can add app settings to your function app deployed to Azure in the Azure portal or the Azure CLI.

Azure 入口網站Azure portal

在 [ Azure 入口網站中,使用 [應用程式設定]](functions-how-to-use-azure-function-app-settings.md#settings)索引JAVA_OPTS標籤來新增設定。In the Azure portal, use the Application Settings tab to add the JAVA_OPTS setting.

Azure CLIAzure CLI

您可以使用az functionapp config appsettings set命令來設定JAVA_OPTS,如下列範例所示:You can use the az functionapp config appsettings set command to set JAVA_OPTS, as in the following example:

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

這個範例會啟用無周邊模式。This example enables headless mode. <APP_NAME>以您的函式應用程式名稱取代<RESOURCE_GROUP> ,並以資源群組取代。Replace <APP_NAME> with the name of your function app, and <RESOURCE_GROUP> with the resource group.

警告

在取用方案中,您必須新增WEBSITE_USE_PLACEHOLDER具有值的0設定。In the Consumption plan, you must add the WEBSITE_USE_PLACEHOLDER setting with a value of 0.
此設定會增加 JAVA 函數的冷啟動時間。This setting does increase the cold start times for Java functions.

第三方程式庫Third-party libraries

Azure Functions 支援使用第三方程式庫。Azure Functions supports the use of third-party libraries. 根據預設,專案pom.xml檔中指定的所有相依性都會在mvn package目標期間自動配套。By default, all dependencies specified in your project pom.xml file are automatically bundled during the mvn package goal. 對於在 pom.xml 檔案中未指定為相依性的程式庫,請將其放入函式根目錄的 lib 目錄中。For libraries not specified as dependencies in the pom.xml file, place them in a lib directory in the function's root directory. 放置在lib目錄中的相依性會在執行時間新增至系統類別載入器。Dependencies placed in the lib directory are added to the system class loader at runtime.

預設會在路徑上提供相依性,而不需要包含lib在目錄中。 com.microsoft.azure.functions:azure-functions-java-libraryThe com.microsoft.azure.functions:azure-functions-java-library dependency is provided on the classpath by default, and doesn't need to be included in the lib directory. 此外, azure 函式-java 背景工作角色會將此處所列的相依性新增至路徑。Also, azure-functions-java-worker adds dependencies listed here to the classpath.

資料類型支援Data type support

您可以使用簡單的舊版 JAVA 物件(pojo)、中azure-functions-java-library所定義的類型或基本資料類型(例如字串和整數)來系結至輸入或輸出系結。You can use Plain old Java objects (POJOs), types defined in azure-functions-java-library, or primitive data types such as String and Integer to bind to input or output bindings.

PojoPOJOs

若要將輸入資料轉換成 POJO,azure 函式-java 背景工作角色會使用gson程式庫。For converting input data to POJO, azure-functions-java-worker uses the gson library. 作為函式輸入的 POJO 類型應為 publicPOJO types used as inputs to functions should be public.

二進位資料Binary data

藉由將 json 中的byte[] dataType欄位設定為binary,將二進位輸入或輸出系結至: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");
    }

如果您預期會有 null 值Optional<T>,請使用。If you expect null values, use Optional<T>.

繫結Bindings

輸入和輸出繫結提供從您的程式碼內連線到資料的宣告式方法。Input and output bindings provide a declarative way to connect to data from within your code. 一個函數可以有多個輸入和輸出繫結。A function can have multiple input and output bindings.

輸入系結範例Input binding example

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;
        }
    }
}

您可以使用 HTTP 要求叫用此函式。You invoke this function with an HTTP request.

  • HTTP 要求承載會傳遞做String為引數inputReq的。HTTP request payload is passed as a String for the argument inputReq.
  • 會從資料表儲存體中抓取一個專案,並將它TestInputData當做引數inputData傳遞。One entry is retrieved from Table storage, and is passed as TestInputData to the argument inputData.

若要接收輸入批次,您可以系結String[]POJO[]List<String>、或List<POJO>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;
}

每當設定的事件中樞內有新資料時,就會觸發此函式。This function gets triggered whenever there is new data in the configured event hub. 因為設定為MANY,所以函式會從事件中樞接收一批訊息。cardinalityBecause the cardinality is set to MANY, the function receives a batch of messages from the event hub. EventData從事件中樞轉換為TestEventData ,以執行函式。EventData from event hub gets converted to TestEventData for the function execution.

輸出繫結範例Output binding example

您可以使用$return,將輸出系結系結至傳回值。You can bind an output binding to the return value by 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;
    }
}

如果有多個輸出繫結,請只對其中一個使用傳回值。If there are multiple output bindings, use the return value for only one of them.

若要傳送多個輸出值,請使用 azure-functions-java-library 套件中定義的 OutputBinding<T>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;
    }

您在 HttpRequest 上叫用此函式。You invoke this function on an HttpRequest. 它會將多個值寫入佇列儲存體。It writes multiple values to Queue storage.

HttpRequestMessage 和 HttpResponseMessageHttpRequestMessage and HttpResponseMessage

這些是在中azure-functions-java-library定義。These are defined in azure-functions-java-library. 它們是可與 HttpTrigger 函式搭配使用的協助程式類型。They are helper types to work with HttpTrigger functions.

特殊類型Specialized type 目標Target 一般使用方式Typical usage
HttpRequestMessage<T> HTTP 觸發程序HTTP Trigger 取得方法、標頭或查詢Gets method, headers, or queries
HttpResponseMessage HTTP 輸出繫結HTTP Output Binding 傳回200以外的狀態Returns status other than 200

中繼資料Metadata

有幾個觸發程序會將觸發程序中繼資料與輸入資料一起傳送。Few triggers send trigger metadata along with input data. 您可以使用批註@BindingName來系結至觸發程式中繼資料。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);
    }
}

在上述範例中, queryValue會系結至 HTTP 要求 URL http://{example.host}/api/metadata?name=testname的查詢字串參數。In the preceding example, the queryValue is bound to the query string parameter name in the http request URL, http://{example.host}/api/metadata?name=test. 以下是另一個範例,顯示如何從佇列Id觸發程式中繼資料系結至。Here's another example, showing how to bind 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);
    }

注意

注釋中提供的名稱必須符合中繼資料屬性。The name provided in the annotation needs to match the metadata property.

執行內容Execution context

ExecutionContext定義于中azure-functions-java-library,包含可與函數執行時間通訊的 helper 方法。ExecutionContext, defined in the azure-functions-java-library, contains helper methods to communicate with the functions runtime.

記錄器Logger

使用getLogger(定義于ExecutionContext)從函式程式碼寫入記錄。Use getLogger, defined in ExecutionContext, to write logs from function code.

範例: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);
    }
}

檢視記錄和追蹤View logs and trace

您可以使用 Azure CLI 來串流 JAVA stdout 和 stderr 記錄,以及其他應用程式記錄。You can use the Azure CLI to stream Java stdout and stderr logging, as well as other application logging.

以下是如何設定函式應用程式,使用 Azure CLI 來撰寫應用程式記錄的方法:Here's how to configure your function app to write application logging by using the Azure CLI:

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

若要使用 Azure CLI 來串流函式應用程式的記錄輸出,請開啟新的命令提示字元、Bash 或終端機會話,然後輸入下列命令:To stream logging output for your function app by 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

Az webapp log tail命令具有使用--provider選項來篩選輸出的選項。The az webapp log tail command has options to filter output by using the --provider option.

若要使用 Azure CLI,以單一 ZIP 檔案的形式下載記錄檔,請開啟新的命令提示字元、Bash 或終端機會話,然後輸入下列命令:To download the log files as a single ZIP file by 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

在執行此命令之前,您必須先啟用 Azure 入口網站或 Azure CLI 中的檔案系統記錄。You must have enabled file system logging in the Azure portal or the Azure CLI before running this command.

環境變數Environment variables

在 Functions 中,應用程式設定 (例如服務連接字串) 在執行期間會公開為環境變數。In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. 您可以使用System.getenv("AzureWebJobsStorage")來存取這些設定。You can access these settings by using, System.getenv("AzureWebJobsStorage").

下列範例會取得應用程式設定,並使用名為myAppSetting的機碼:The following example gets the application setting, with the key named myAppSetting:


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

後續步驟Next steps

如需有關 Azure Functions JAVA 開發的詳細資訊,請參閱下列資源:For more information about Azure Functions Java development, see the following resources: