将 Java 函数连接到 Azure 存储Connect your Java function to Azure Storage

无需编写自己的集成代码,即可使用 Azure Functions 将 Azure 服务和其他资源连接到函数。Azure Functions lets you connect Azure services and other resources to functions without having to write your own integration code. 这些绑定表示输入和输出,在函数定义中声明。 These bindings, which represent both input and output, are declared within the function definition. 绑定中的数据作为参数提供给函数。Data from bindings is provided to the function as parameters. 触发器是一种特殊类型的输入绑定。 A trigger is a special type of input binding. 尽管一个函数只有一个触发器,但它可以有多个输入和输出绑定。Although a function has only one trigger, it can have multiple input and output bindings. 有关详细信息,请参阅 Azure Functions 触发器和绑定的概念To learn more, see Azure Functions triggers and bindings concepts.

本文介绍如何将前一篇快速入门文章中创建的函数与 Azure 存储队列相集成。This article shows you how to integrate the function you created in the previous quickstart article with an Azure Storage queue. 添加到此函数的输出绑定会将 HTTP 请求中的数据写入到队列中的消息。The output binding that you add to this function writes data from an HTTP request to a message in the queue.

大多数绑定都需要一个存储的连接字符串,函数将使用该字符串来访问绑定的服务。Most bindings require a stored connection string that Functions uses to access the bound service. 为便于建立此连接,请使用连同函数应用一起创建的存储帐户。To make this connection easier, you use the Storage account that you created with your function app. 与此帐户建立的连接已存储在名为 AzureWebJobsStorage 的应用设置中。The connection to this account is already stored in an app setting named AzureWebJobsStorage.

先决条件Prerequisites

在开始学习本文之前,请完成 Java 快速入门第 1 部分中的步骤。Before you start this article, complete the steps in part 1 of the Java quickstart.

下载函数应用设置Download the function app settings

你已在 Azure 中创建了一个函数应用以及所需的存储帐户。You've already created a function app in Azure, along with the required Storage account. 此帐户的连接字符串安全存储在 Azure 中的应用设置内。The connection string for this account is stored securely in app settings in Azure. 在本文中,你要将消息写入到同一帐户中的存储队列。In this article, you write messages to a Storage queue in the same account. 若要在本地运行函数时连接到该存储帐户,必须将应用设置下载到 local.settings.json 文件。To connect to your Storage account when running the function locally, you must download app settings to the local.settings.json file.

从项目的根目录中,运行以下 Azure Functions Core Tools 命令将设置下载到 local.settings.json,并将 <APP_NAME> 替换为上一篇文章中函数应用的名称:From the root of the project, run the following Azure Functions Core Tools command to download settings to local.settings.json, replacing <APP_NAME> with the name of your function app from the previous article:

func azure functionapp fetch-app-settings <APP_NAME>

可能需要登录到 Azure 帐户。You might need to sign in to your Azure account.

Important

此命令将用 Azure 中函数应用的值覆盖任何现有设置。This command overwrites any existing settings with values from your function app in Azure.

由于 local.settings.json 文件包含机密,因此永远不会发布它,应将其从源代码管理中排除。Because it contains secrets, the local.settings.json file never gets published, and it should be excluded from source control.

需要 AzureWebJobsStorage 值,即存储帐户连接字符串。You need the value AzureWebJobsStorage, which is the Storage account connection string. 你将使用此连接来验证输出绑定是否按预期方式工作。You use this connection to verify that the output binding works as expected.

启用扩展捆绑包Enable extension bundles

安装绑定扩展的最简单方法是启用扩展捆绑包The easiest way to install binding extensions is to enable extension bundles. 启用捆绑包时,会自动安装一组预定义的扩展包。When you enable bundles, a predefined set of extension packages is automatically installed.

若要启用扩展捆绑包,请打开 host.json 文件并更新其内容以匹配以下代码:To enable extension bundles, open the host.json file and update its contents to match the following code:

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[1.*, 2.0.0)"
    }
}

现在,可将存储输出绑定添加到项目。You can now add the Storage output binding to your project.

添加输出绑定Add an output binding

在 Java 项目中,绑定被定义为函数方法上的绑定注释。In a Java project, the bindings are defined as binding annotations on the function method. 然后根据这些注释自动生成 function.json 文件。The function.json file is then autogenerated based on these annotations.

浏览到函数代码在 src/main/java 下的位置,打开 Function.java 项目文件,然后将以下参数添加到 run 方法定义:Browse to the location of your function code under src/main/java, open the Function.java project file, and add the following parameter to the run method definition:

@QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") OutputBinding<String> msg

msg 参数为 OutputBinding<T> 类型,表示函数完成时作为消息写入到输出绑定的字符串集合。The msg parameter is an OutputBinding<T> type, which represents a collection of strings that are written as messages to an output binding when the function completes. 在这种情况下,输出是名为的 outqueue 存储队列。In this case, the output is a storage queue named outqueue. 存储帐户的连接字符串由 connection 方法设置。The connection string for the Storage account is set by the connection method. 请传递包含存储帐户连接字符串的应用程序设置,而不是传递连接字符串本身。Rather than the connection string itself, you pass the application setting that contains the Storage account connection string.

run 方法定义现在应如以下示例所示:The run method definition should now look like the following example:

@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION)  
        HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") 
        OutputBinding<String> msg, final ExecutionContext context) {
    ...
}

添加使用输出绑定的代码Add code that uses the output binding

现在可以使用新的 msg 参数,从函数代码写入到输出绑定。Now, you can use the new msg parameter to write to the output binding from your function code. 将以下代码行添加到成功响应之前,以便将 name 的值添加到 msg 输出绑定。Add the following line of code before the success response to add the value of name to the msg output binding.

msg.setValue(name);

使用输出绑定时,无需使用 Azure 存储 SDK 代码进行身份验证、获取队列引用或写入数据。When you use an output binding, you don't have to use the Azure Storage SDK code for authentication, getting a queue reference, or writing data. Functions 运行时和队列输出绑定将为你执行这些任务。The Functions runtime and queue output binding do those tasks for you.

run 方法现在应如以下示例所示:Your run method should now look like the following example:

@FunctionName("HttpTrigger-Java")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", methods = {HttpMethod.GET, HttpMethod.POST}, authLevel = AuthorizationLevel.FUNCTION) HttpRequestMessage<Optional<String>> request, 
        @QueueOutput(name = "msg", queueName = "outqueue", connection = "AzureWebJobsStorage") 
        OutputBinding<String> msg, final ExecutionContext context) {
    context.getLogger().info("Java HTTP trigger processed a request.");

    // Parse query parameter
    String query = request.getQueryParameters().get("name");
    String name = request.getBody().orElse(query);

    if (name == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build();
    } else {
        // Write the name to the message queue. 
        msg.setValue(name);

        return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
    }
}

更新测试Update the tests

由于原型还创建一组测试,因此需更新这些测试,以便处理 run 方法签名中的新 msg 参数。Because the archetype also creates a set of tests, you need to update these tests to handle the new msg parameter in the run method signature.

浏览到测试代码在 src/test/java 下的位置,打开 Function.java 项目文件,将 //Invoke 下的代码行替换为以下代码。Browse to the location of your test code under src/test/java, open the Function.java project file, and replace the line of code under //Invoke with the following code.

@SuppressWarnings("unchecked")
final OutputBinding<String> msg = (OutputBinding<String>)mock(OutputBinding.class);

// Invoke
final HttpResponseMessage ret = new Function().run(req, msg, context);

现在可以在本地试用新输出绑定了。You're now ready to try out the new output binding locally.

在本地运行函数Run the function locally

如前所述,使用以下命令在本地生成项目并启动 Functions 运行时:As before, use the following command to build the project and start the Functions runtime locally:

mvn clean package 
mvn azure-functions:run

Note

由于已在 host.json 中启用扩展捆绑包,因此在启动期间已下载并安装存储绑定扩展以及其他 Microsoft 绑定扩展。Because you enabled extension bundles in the host.json, the Storage binding extension was downloaded and installed for you during startup, along with the other Microsoft binding extensions.

如前所述,使用 cURL 在新的终端窗口中从命令行触发函数:As before, trigger the function from the command line using cURL in a new terminal window:

curl -w "\n" http://localhost:7071/api/HttpTrigger-Java --data AzureFunctions

这一次,输出绑定还会在存储帐户中创建名为 outqueue 的队列,并添加包含此字符串的消息。This time, the output binding also creates a queue named outqueue in your Storage account and adds a message with this same string.

接下来,使用 Azure CLI 查看新队列,并检查是否已添加了一条消息。Next, you use the Azure CLI to view the new queue and verify that a message was added. 也可以使用 Azure 存储资源管理器Azure 门户查看队列。You can also view your queue by using the Azure Storage Explorer or in the Azure portal.

设置存储帐户连接Set the Storage account connection

打开 local.settings.json 文件并复制 AzureWebJobsStorage 的值(即存储帐户连接字符串)。Open the local.settings.json file and copy the value of AzureWebJobsStorage, which is the Storage account connection string. 使用以下 Bash 命令将 AZURE_STORAGE_CONNECTION_STRING 环境变量设置为该连接字符串:Set the AZURE_STORAGE_CONNECTION_STRING environment variable to the connection string by using this Bash command:

AZURE_STORAGE_CONNECTION_STRING="<STORAGE_CONNECTION_STRING>"

AZURE_STORAGE_CONNECTION_STRING 环境变量中设置连接字符串时,无需每次都要提供身份验证,即可访问你的存储帐户。When you set the connection string in the AZURE_STORAGE_CONNECTION_STRING environment variable, you can access your Storage account without having to provide authentication each time.

查询存储队列Query the Storage queue

可以使用 az storage queue list 命令查看帐户中的存储队列,如以下示例所示:You can use the az storage queue list command to view the Storage queues in your account, as in the following example:

az storage queue list --output tsv

此命令的输出包含名为 outqueue 的队列,即运行函数时创建的队列。The output from this command includes a queue named outqueue, which is the queue that was created when the function ran.

接下来,使用 az storage message peek 命令查看此队列中的消息,如以下示例所示:Next, use the az storage message peek command to view the messages in this queue, as in this example:

echo `echo $(az storage message peek --queue-name outqueue -o tsv --query '[].{Message:content}') | base64 --decode`

返回的字符串应与发送的用于测试函数的消息相同。The string returned should be the same as the message you sent to test the function.

Note

以上示例从 base64 解码返回的字符串。The previous example decodes the returned string from base64. 这是因为,队列存储绑定以 base64 字符串的形式写入和读取 Azure 存储。This is because the Queue storage bindings write to and read from Azure Storage as base64 strings.

重新部署项目Redeploy the project

若要更新已发布的应用,请再次运行以下命令:To update your published app, run the following command again:

mvn azure-functions:deploy

同样,可以使用 cURL 来测试已部署的函数。Again, you can use cURL to test the deployed function. 如前所述,将 POST 请求正文中的值 AzureFunctions 传递到 URL,如以下示例所示:As before, pass the value AzureFunctions in the body of the POST request to the URL, as in this example:

curl -w "\n" https://fabrikam-functions-20190929094703749.chinacloudsites.cn/api/HttpTrigger-Java?code=zYRohsTwBlZ68YF.... --data AzureFunctions

可以再次检查存储队列消息,以验证输出绑定是否按预期在队列中生成新消息。You can examine the Storage queue message again to verify that the output binding generates a new message in the queue, as expected.

清理资源Clean up resources

本教程系列中的其他快速入门教程是在本文的基础上制作的。Other quickstarts in this collection build upon this quickstart. 如果打算继续学习后续的快速入门或相关教程,请不要清理在本快速入门中创建的资源。If you plan to continue on with subsequent quickstarts or with the tutorials, don't clean up the resources created in this quickstart. 如果不打算继续学习,请使用以下命令删除在本快速入门中创建的所有资源:If you don't plan to continue, use the following command to delete all resources created in this quickstart:

az group delete --name myResourceGroup

出现提示时选择 ySelect y when prompted.

后续步骤Next steps

现已更新 HTTP 触发的函数,使其将数据写入存储队列。You've updated your HTTP-triggered function to write data to a Storage queue. 若要详细了解如何使用 Java 开发 Azure Functions,请参阅 Azure Functions Java 开发人员指南Azure Functions 触发器和绑定To learn more about developing Azure Functions with Java, see the Azure Functions Java developer guide and Azure Functions triggers and bindings. 有关 Java 中完整 Function 项目的示例,请参阅 Java Functions 示例For examples of complete Function projects in Java, see the Java Functions samples.