目前我正在开发一个迷你项目,我正在设计一个在S3中托管的静态网站。有一个“上传”页面,用户可在其中输入姓名,电子邮件和手机号码和文件,然后点击“上传”按钮调用API网址终端。我创建了API网关url端点“https://myAPIName.execute-api.ap-region-1.amazonaws.com/Testing/TestinLambda2”,我在其上使用XMLHTTPRequest调用post请求并像这样发送 -
xhttp.open("POST", "https://myAPIName.execute-api.ap-region-1.amazonaws.com/Testing/TestinLambda2", true);
xhttp.send(JSON.stringify({Name:$('#Name').val(),Email:$('#email').val(),MobileNo:$('#mno').val()}));
我将数据作为JSON输入发送到aws lambda Java函数。
我还没有在AWS API网关中完成任何正文映射设置。
回到AWS方面,我正在使用AWS Lambda Java函数使用POJO。以下是我从AWS lambda文档中获取的类 -
我的Lambda函数
package com.amazonaws.lambda.demo;
import java.util.Map;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class FirstLambda implements RequestHandler<InputClass, OutputClass> {
@Override
public OutputClass handleRequest(InputClass input, Context context) {
String greetingString = String.format("Hello %s, %s , %s.", input.getName(), input.getEmail(), input.getMobile());
//String greetingString = String.format("Hello");
return new OutputClass(greetingString);
}
}
我的输入类
package com.amazonaws.lambda.demo;
public class InputClass {
String Name;
String Email;
String MobileNo;
public String getName(){
return this.Name;
}
public String getEmail(){
return this.Email;
}
public String getMobile(){
return this.MobileNo;
}
public void setName(String Name){
this.Name = Name;
}
public void setEmail(String Email){
this.Email = Email;
}
public void setMobile(String Mobile){
this.MobileNo = Mobile;
}
public InputClass(){
}
public InputClass(String Name, String Email, String Mobile){
this.Name = Name;
this.Email = Email;
this.MobileNo = Mobile;
}
}
我的输出类
public class OutputClass {
String greetings;
public String getStrings()
{
return greetings;
}
public void setString()
{
this.greetings = greetings;
}
public OutputClass(String greetings)
{
this.greetings = greetings;
}
public OutputClass()
{
}
}
当我点击“上传”按钮时,我将屏幕上的值设为 -
{"strings":"Hello null, null , null."}
这与使用“Test”选项在API网关中测试POST方法时获得的值相同。
如果有人可以指出我在这里缺少什么,我真的很感激。
非常感谢!
答案 0 :(得分:1)
杰拉德(Gerards)尝试重现问题的原因不起作用,是因为他使用测试事件而不是通过apigateway进行了尝试。
这里发生的是,当您通过网关调用lambda时,您发送的整个json封装在另一个对象中,该对象具有其他详细信息,例如pathparameters和其他相关详细信息。 为了对此进行测试,您可以创建一个新的POJO并将InputClass作为其中的成员。将lambda参数更改为新的POJO,然后再次通过api网关调用lambda。
这将为您提供所需的数据。
答案 1 :(得分:0)
为了简单起见,我使用您使用Lambda测试事件代替API网关提供的类对此进行了测试,修复程序也应该继续使用您的JavaScript。
似乎无论你如何命名代码中的类变量,JSON中的参数都必须遵循getter / setter的名称。只需更正代码中的属性即可解决问题。这是有道理的,因为无法从包外部访问类变量。所以你必须遵循mutator方法的名称。
xhttp.open("POST", "https://myAPIName.execute-api.ap-region-1.amazonaws.com/Testing/TestinLambda2", true);
xhttp.send(JSON.stringify({name: $('#Name').val(), email: $('#email').val(), mobile: $('#mno').val()}));
以下有效负载:
{
"Name": "Gerard",
"Email": "abc@123.com",
"MobileNo": "8675309"
}
生成
{"strings":"Hello null, null , null."}
此有效载荷
{
"name": "Gerard",
"email": "abc@123.com",
"mobile": "8675309"
}
产生预期的响应:
{"strings": "Hello Gerard, abc@123.com , "8675309"."}
答案 2 :(得分:0)
如果您的AWS Lambda位于API网关后面,则网关将转换传入的有效负载并将其以其他格式(您可能期望的格式)传递到AWS Lambda。
它添加有关请求的一些元数据(例如标头),并将所有内容包装为JSON,格式如下:
{
"headers": {}
"body": ""
...
}
此JSON传递到Java AWS Lambda函数。您可以通过使用以下签名临时调整RequestHandler
来查看一下:
public class FirstLambda implements RequestHandler<Map<String, Object>, OutputClass> {
@Override
public OutputClass handleRequest(Map<String, Object> input, Context context) {
input.forEach((key, value) -> System.out.println(key + ":" + value);
return new OutputClass("");
}
}
每当您使用AWS控制台并使用简单的有效负载(例如
)发送测试事件时{
"Name": "Duke",
"Email": "mail@whatever.io"
}
它不反映当您使用API网关调用Lambda时收到的有效负载,例如卷发或邮递员。
因此,在您的情况下,应使用Jackson或GSON将有效载荷的String
字段内的body
序列化到您的POJO。
如果您不想使用通用Map
,也可以添加
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>3.1.0</version>
</dependency>
转到您的项目,并使用APIGatewayProxyRequestEvent
和APIGatewayProxyResponseEvent
包装器类以及访问标头,正文等。
public class FirstLambda implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEventinput, Context context) {
System.out.println(input.getBody());
// e.g. use the ObjectMapper from Jackson to parse the String body to your POJO
APIGatewayProxyResponseEvent result = new APIGatewayProxyResponseEvent();
result.setStatusCode(200);
result.setBody(objectMapper.writeValueAsString(new OutputClass(""));
return result;
}
}
另一种解决方案是调整API网关将数据传递到Lambda函数的方式,如here
所述