我已经制作了一个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)"
]
}
}
}
答案 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
类型更改为 Object
、Map<String,Object>
或 MyPojo
使解析器满意的原因。
如果 input
确实应该是一个字符串,则负载值本身必须以 "
开头。例如,String payload = "\"string input\""
。