AWS无法从START_OBJECT

时间:2016-05-11 07:15:35

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

我已经制作了一个Lambda函数,我希望借助API网关通过URL访问它。

我已经设置了所有内容,我还在API网关中创建了一个application/json正文映射模板,如下所示:

{ 
    "input": "$input.params('input')",
}

然后我触发HTTP GET请求,如下所示:

https://dmquh95ckh.execute-api.eu-west-1.amazonaws.com/prod/OtoTestFunction?input=test

我的Java处理程序类如下所示:

public class LambdaFunctionHandler implements RequestHandler<String, String> {

    @Override
    public String handleRequest(String input, Context context) {
        context.getLogger().log("Input: " + input);
        return "Test completed."+input;
    }
}

这是完整的错误消息:

{
  "errorMessage": "An error occurred during JSON parsing",
  "errorType": "java.lang.RuntimeException",
  "stackTrace": [],
  "cause": {
    "errorMessage": "com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: lambdainternal.util.NativeMemoryAsInputStream@68c4039c; line: 1, column: 1]",
    "errorType": "java.io.UncheckedIOException",
    "stackTrace": [],
    "cause": {
      "errorMessage": "Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: lambdainternal.util.NativeMemoryAsInputStream@68c4039c; line: 1, column: 1]",
      "errorType": "com.fasterxml.jackson.databind.JsonMappingException",
      "stackTrace": [
        "com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)",
        "com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:835)",
        "com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:59)",
        "com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:12)",
        "com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1441)",
        "com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1047)"
      ]
    }
  }
}

5 个答案:

答案 0 :(得分:5)

这是Lambda反序列化期间的错误消息。

您的API网关映射模板正在发送JSON对象,但您的处理程序正在使用String。从API网关发送原始字符串,或更新处理程序以使用与模板输出对应的POJO。

public class MyPojo {
   private String input;
   public String getInput() { return input; }
   public void setInput(String input) { this.input = input; }
}

请参阅: http://docs.aws.amazon.com/lambda/latest/dg/java-programming-model-req-resp.html

答案 1 :(得分:0)

当我将输入参数的类型从 String更改为Object 时,它在所有情况下都对我有用。

public class LambdaFunctionHandler implements RequestHandler<Object, String> {

  @Override
  public String handleRequest(Object input, Context context) {
    String data= input != null ? input.toString() : "{}";
    context.getLogger().log("Input: " + data);
    return "Test completed."+data;
  }
}

答案 2 :(得分:0)

我尝试使用Object作为参数类型以及Pojo类,它在某些情况下可以工作,但是当使用API​​网关URL从浏览器发出请求时,它失败并给出了上述确切错误。至少花2-3个小时找出正确的签名(大多数情况下可以使用),如下所示。但这是举个hello world示例,您显然可以根据需要自定义输入。

public class LambdaFunctionHandler implements RequestHandler<***Map<String,Object>,***  Customer> { 
    @Override
    public Customer handleRequest(***Map<String,Object> input***, Context context) {

    }
}

答案 3 :(得分:0)

InputStream应该能够处理任何输入。

参考: https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html

InputStream –事件是任何JSON类型。运行时无需修改即可将文档的字节流传递给处理程序。您可以对输入进行反序列化,然后将输出写入输出流。

public class Handler implements RequestHandler<InputStream, String> {
@Override
    public String handleRequest(InputStream event, Context context) {

答案 4 :(得分:0)

错误消息试图说明“由于 input 是一个字符串,我希望它以引号 " 开头。但我看到的是 {”。这就是将 input 类型更改为 ObjectMap<String,Object>MyPojo 使解析器满意的原因。

如果 input 确实应该是一个字符串,则负载值本身必须以 " 开头。例如,String payload = "\"string input\""