【问题标题】:Correct way to use optional parameter in Java Azure Function在 Java Azure 函数中使用可选参数的正确方法
【发布时间】:2019-03-19 14:08:55
【问题描述】:

我试图弄清楚如何使用 Java 和一个简单的温度转换函数来创建 Azure Functions。我试图定义的路线是:

temps/{method}/{temp?}

我已经修改了为新 Java 项目生成的模板化 HttpTrigger 代码:

   @FunctionName("temps")
   public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
                    methods = {HttpMethod.GET}, 
                    authLevel = AuthorizationLevel.ANONYMOUS,
                    route = "temps/{method}/{temp:float?}") 
            HttpRequestMessage<Optional<String>> request,
            @BindingName("method") String method,
            @BindingName("temp") String temp,
            final ExecutionContext context) {...}

当我实际将温度值作为最后一个参数传递时,它工作正常,但如果我只是调用“temps/{method}”,我会在

处得到 NullPointerException

com.microsoft.azure.functions.worker.binding.BindingDataStore.getTriggerMetatDataByName(BindingDataStore.java:54). 

所以我假设我没有正确定义绑定,以便当最后一个参数不包含在 URI 中时它可以正确处理。我看过许多其他关于此的帖子,其中包括“?”应该工作,所以想知道我是否遗漏了一些明显的东西。注意:我有代码来测试在 temp 中传递的值是否是浮点值,所以可以正常工作。

【问题讨论】:

    标签: java azure azure-functions


    【解决方案1】:

    我发现了另一个帖子,其中包含一个示例,如果不包含可选参数,则提供默认值:

        @FunctionName("temps")
        public HttpResponseMessage run(
            @HttpTrigger(name = "req", 
                        methods = {HttpMethod.GET}, 
                        authLevel = AuthorizationLevel.ANONYMOUS,
                        route = "temps/{method}/{temp=NONE}") 
                HttpRequestMessage<Optional<String>> request,
                @BindingName("method") String method,
                @BindingName("temp") String temp,
                final ExecutionContext context) {...}
    

    这似乎可行,但它不能解释为什么其他发布的示例带有“?”指定一个可选参数不要(除非它在 ​​Java 中不起作用但在 C# 中起作用)。我还发现,在提供默认值时,您似乎不能同时包含参数类型,例如“{temp**:float**=NONE}”。

    【讨论】:

      【解决方案2】:

      我认为 Java 中的路由参数存在多个问题。 实际上,我在 Java 中的 Azure 函数的 GitHub 存储库中创建了一个关于这个问题的问题,我也必须处理这个问题,不要犹豫,添加更多你可能拥有的细节,这样它可能会得到更多关注:https://github.com/Azure/azure-functions-java-worker/issues/293

      编辑:

      这是另一种可能的解决方法,适用于参数类型(实际上,此解决方案仅在指定参数类型时才有效):使用问号编写参数,但不要使用@BindingName 注释。而是直接在函数中解析 URL。

      例如:

      @FunctionName("example")
      public HttpResponseMessage exampleFunction (
          @HttpTrigger(
              name = "functionTrigger",
              authLevel = AuthorizationLevel.ANONYMOUS,
              methods = {HttpMethod.GET},
              route = "example/{param1:int?}/{param2:int?}" // specify the parameters like this
          ) final HttpRequestMessage<Optional<String>> request,
          final ExecutionContext context
      ) {
          String[] parameters = request.getUri().getPath().split("/"); // though types were specified, with this way of doing you retrieve the parameters as strings
          int param1 = 0;
          int param2 = 0;
          if (parameters.length > 3) {
              param1 = Integer.parseInt(parameters[3]);
              if (parameters.length > 4) {
                  param2 = Integer.parseInt(parameters[4]);
              }
          }
          return request.createResponseBuilder(HttpStatus.OK)
              .body("You sent " + param1 + " and " + param2)
              .build();
      }
      

      精度:尽管您将参数作为字符串检索,但您在路由路径中指定类型的事实会阻止用户发送不同类型的值(如果他们尝试这样做,该函数将自动响应 404 Not成立)。

      另外,这也是使此解决方法远非理想解决方案的原因,您必须注意 URL 路径中的“/”数量(例如,不要忘记紧跟在域,如果您尚未删除它等)。

      【讨论】:

      • 欢迎来到 Stack Overflow!虽然这在理论上可以回答问题,it would be preferable 在此处包含答案的基本部分,并提供链接以供参考。
      猜你喜欢
      • 2015-04-06
      • 1970-01-01
      • 2013-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-17
      • 1970-01-01
      相关资源
      最近更新 更多