我是Java的新手,所以这可能与AWS lambda根本没有关系。然而,lambda对输入/输出对象采取了这样的自由,我认为它是罪魁祸首。
我正在构建我的第一个lambda函数,并希望返回一个简单的JSON结构(在本例中进一步简化):
{
"document" : "1",
"person" : { "name" : "John Doe" }
}
然而,当lambda序列化JSON时,它总是设置" person"一个空白的物体!
{
"document": "1",
"person": {}
}
以下是我的完整代码:
- test1.java
package handler_test;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class test1 implements RequestHandler<String, ResponseClass> {
@Override
public ResponseClass handleRequest(String input, Context context) {
return new ResponseClass();
}
}
- ResponseClass.java
package handler_test;
import org.json.JSONException;
import org.json.JSONObject;
public class ResponseClass {
String document;
JSONObject person;
public String getdocument() {
return "1";
}
public JSONObject getperson() {
try {
return new JSONObject("{ \"name\" : \"John Doe\" }");
} catch (JSONException e1) {
System.out.println("error creating jsonobject");
return null;
}
}
public ResponseClass() {
}
}
我尝试了几十种变体,使用对象而不是JSONObjects,将getperson输出转换为字符串(如果我想要一个字符串,则可以工作)等等。如果我存储值并将它们打印到记录器,没关系。但是一旦我试图通过lambda返回它就会变成梨形。我已经梳理了网络,除了亚马逊的#34;问候&#34;之外,还无法在AWS-lambda java响应对象上找到更多信息。示例代码,只包含两个字符串。任何建议都非常感谢!
答案 0 :(得分:4)
我使用流处理程序解决了这个问题,它不仅可以工作,而且还有更多的控制权和更少的代码!我使用gson进行JSON序列化/反序列化,使用Apache IOUtils将inputteam转换为字符串。由于我已经使用Request和Response类编写了它,我继续使用它们,尽管我能够摆脱所有的getter和setter代码。
两个说明: 1. gson将输出Response类的所有非null属性,甚至 如果它们被宣布为私有,那么如果有你不想要的值 吐回来确保在最后一行之前将它们设置为null。 2.将Eclipse IDE与AWS插件一起使用时,除非可以找到RequestHandler,否则它不会将代码上传到AWS!因此,我有一个立即覆盖的存根函数。
import com.google.gson.*;
import org.apache.commons.io.IOUtils;
import com.amazonaws.services.lambda.runtime.*;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
public class Intel implements RequestStreamHandler, RequestHandler<Object, Object> {
@Override
public Object handleRequest(Object input, Context context) {
return null;
}
@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
Request req = new Gson().fromJson(IOUtils.toString(inputStream, "UTF-8"), Request.class);
Response resp = new ResponseClass();
resp.id = 1;
resp.person.name = req.name;
et_home_phone(req.name);
outputStream.write(new Gson().toJson(resp).getBytes(Charset.forName("UTF-8")));
}
private void get_home_phone(String name) {
// call external API -- stub example! Assumes only one phone returned
// in the format { "number" : "123-456-7890", "type" = "home" }
// gson magic assures they get copied to the keys of the same name
HttpGet httpGet = new HttpGet(phoneURL + "/" + name));
HttpResponse httpResponse = client.execute(httpGet);
resp.phone[0] = new Gson().fromJson(IOUtils.toString(httpResponse .getEntity().getContent(), "UTF-8"), Response.Phone.class);
}
}
public class Response {
public class Person {
String name;
}
public class Phone {
String number;
String type;
}
public Integer id;
public Person person = new Person();
public Phone[] phone = new Phone[5];
}
答案 1 :(得分:1)
您可以跳过JSONObject
并使用POJO作为嵌套类。但是,根据惯例命名在这里很重要。确保使用camel case命名访问者方法(get + name of property capitalized)。试试这个:
public class ResponseClass {
String document;
Person person;
public String getDocument() {
return "1";
}
public Person getPerson() {
return person;
}
}
class Person {
String name;
public String getName() {
return name;
}
}
答案 2 :(得分:0)
摘自文档:https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html
“如果它是包装原始值的类型,则运行时将返回该值的文本表示形式。”
因此具有单个字符串属性的简单人类将返回如下内容:
{ "document": "1", "person": "john doe" }
将另一个字段添加到人员类别,它将按需要工作:
class Person {
String firstName;
String lastName;
...
}
输出:
{ "document": "1", "person": { "firstName": "John", "lastName": "Doe" }}