【问题标题】:Curl on AWS LambdaAWS Lambda 上的卷曲
【发布时间】:2022-08-13 05:21:57
【问题描述】:

我用 Java 编写了一个简单的 aws lambda 函数:

我的处理程序看起来像这样

public class HelloAWS implements RequestHandler<Map<String,String>, Object>{

@Override
public Object handleRequest(Map<String,String> i, Context cntxt) {
        String input = i.values().toString();
        return \"Hello World via Lambda and Java!\" + input;
}

AWS 仪表板测试的输出看起来像我期望的那样: \"Hello World 通过 Lambda 和 Java![value1, value2, value3]\"

我正在尝试使用 Ubuntu curl 重现此测试结果:

curl \"https://myUrl.lambda-url.us-east-1.on.aws/\" -X POST -H \"Content-type: application/json\" -d \'{\"key1\": \"value1\"}\'

这会产生一个错误:

An error occurred during JSON parsing: java.lang.RuntimeException
java.lang.RuntimeException: An error occurred during JSON parsing
Caused by: java.io.UncheckedIOException: com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
 at [Source: (ByteArrayInputStream); line: 1, column: 84] (through reference chain: java.util.LinkedHashMap[\"headers\"])
    at com.amazonaws.services.lambda.runtime.serialization.factories.JacksonFactory$InternalSerializer.fromJson(JacksonFactory.java:184)
Caused by: com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
 at [Source: (ByteArrayInputStream); line: 1, column: 84] (through reference chain: java.util.LinkedHashMap[\"headers\"])
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1445)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1219)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1129)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:63)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:10)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:527)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1719)
    at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1228)
    at com.amazonaws.services.lambda.runtime.serialization.factories.JacksonFactory$InternalSerializer.fromJson(JacksonFactory.java:182)
An error occurred during JSON parsing: java.lang.RuntimeException java.lang.RuntimeException: An error occurred during JSON parsing Caused by: java.io.UncheckedIOException: com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token at [Source: (ByteArrayInputStream); line: 1, column: 84] (through reference chain: java.util.LinkedHashMap[\"headers\"]) at com.amazonaws.services.lambda.runtime.serialization.factories.JacksonFactory$InternalSerializer.fromJson(JacksonFactory.java:184) Caused by: com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token at [Source: (ByteArrayInputStream); line: 1, column: 84] (through reference chain: java.util.LinkedHashMap[\"headers\"]) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1445) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1219) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1129) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:63) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:10) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:527) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1719) at com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1228) at com.amazonaws.services.lambda.runtime.serialization.factories.JacksonFactory$InternalSerializer.fromJson(JacksonFactory.java:182)

我发现多个来源表明我应该能够像这样卷曲我的服务:

https://aws.amazon.com/blogs/aws/announcing-aws-lambda-function-urls-built-in-https-endpoints-for-single-function-microservices/

https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html

为什么 Java 对仪表板测试和 curl 请求的处理方式不同?

    标签: java amazon-web-services aws-lambda


    【解决方案1】:

    您可以使用 API 网关来配置您的 Lambda 函数,以便您可以通过 CURL 调用它。配置 API Gateway 后,您可以调用使用 Java Lambda 运行时 API 构建的 Lambda 函数,命令如下:

    curl -XGET "https://xxxxqjko1o3.execute-api.us-east-1.amazonaws.com/cronstage/employee" 
    

    下面是一个 Java 示例,可引导您完成此过程。此示例中创建的 Lambda 函数还调用 AWS 服务,例如 Amazon DynamoDB。

    Using Amazon API Gateway to invoke Lambda functions

    更新

    我刚刚测试了它,它工作正常。我的 Lambda 函数是使用此 Curl 命令调用的。

    关于在不使用 API Gateway 的情况下调用独立的 Lambda 函数,请参阅这篇可能在此处有所帮助的新文章:

    Announcing AWS Lambda Function URLs: Built-in HTTPS Endpoints for Single-Function Microservices

    已确认 - 我关注了那篇新文章,它为您提供了一个 URL,您可以使用它通过 CURL 调用而无需 API 网关......

    部署 JAR(Lambda 函数)时 - 确保选择此选项:

    【讨论】:

    • 但是 OP 使用的是 Lambda 函数 URL,而不是 API 网关,docs 似乎表明完全支持这个用例。
    • 我会调查这个。这些文档状态 API 网关也用于此目的 -- docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html
    • 是的,您可以在 Lambda 之前使用 API Gateway,但函数 URL 的全部意义在于您不需要 API Gateway。
    • 它在 Java 中工作——刚刚确认
    • 我相信您的示例使用不同的接口而不是 handleRequest(Map<String,String> i, Context cntxt) - 我的问题是为什么仪表板测试的处理方式与 curl 不同 - 它在使用 handleRequest(Object i, Context cntxt)
    【解决方案2】:
    public class HelloAWS implements RequestHandler<APIGatewayV2HTTPEvent, APIGatewayV2HTTPResponse> {
    
      @Override
      public APIGatewayV2HTTPResponse handleRequest(APIGatewayV2HTTPEvent request, Context context) {
        return null;
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-05
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 2012-08-31
      • 1970-01-01
      • 2015-05-03
      • 1970-01-01
      相关资源
      最近更新 更多