Aws lambda AWS Java Lambda压缩JSON响应失败:";由于配置错误,执行失败:Lambda代理响应格式错误;
我正在从AWS API网关调用AWS Lambda函数。返回的JSON需要压缩,因为它有时会变得太大(主体尺寸太大等)。但是,我在通过API网关获取响应时遇到了一些问题。这是我的Java代码:Aws lambda AWS Java Lambda压缩JSON响应失败:";由于配置错误,执行失败:Lambda代理响应格式错误;,aws-lambda,aws-api-gateway,Aws Lambda,Aws Api Gateway,我正在从AWS API网关调用AWS Lambda函数。返回的JSON需要压缩,因为它有时会变得太大(主体尺寸太大等)。但是,我在通过API网关获取响应时遇到了一些问题。这是我的Java代码: @Override public JSONObject handleRequest(Object input, Context context) { String json_string = ""; try { Gson gson =
@Override
public JSONObject handleRequest(Object input, Context context) {
String json_string = "";
try {
Gson gson = new Gson();
json_string = gson.toJson(input, LinkedHashMap.class);
} catch (ClassCastException ex) {
json_string = (String) input;
}
GenerateJson generateJson = new GenerateJson ();
String body = "";
try {
JSONParser parser = new JSONParser();
Object jsonObj = parser.parse(json_string);
JSONObject matchesobj = (JSONObject) jsonObj;
if (matchesobj.containsKey("body")) {
body = (String) matchesobj.get("body");
} else {
JSONObject error = new JSONObject();
error.put("error", "No body with Base64 data in Request.");
System.out.println(error.toJSONString());
return error;
}
} catch (ParseException ex) {
ex.printStackTrace();
}
byte[] decodedBytes = Base64.getDecoder().decode(body);
String decodedString = new String(decodedBytes);
// System.out.println(decodedString);
JSONObject json = generateJson .getJson(decodedString, "", 2);
JSONObject returnObject = new JSONObject();
JSONObject headers = new JSONObject();
returnObject.put("statusCode", 205);
returnObject.put("isBase64Encoded", true);
// returnObject.put("Content-Encoding", "gzip");
returnObject.put("headers", headers);
returnObject.put("body", compressStringAndReturnBase64(json.toString()));
return (returnObject);
}
public static String compressStringAndReturnBase64(String srcTxt) {
ByteArrayOutputStream rstBao = new ByteArrayOutputStream();
GZIPOutputStream zos;
try {
zos = new GZIPOutputStream(rstBao);
zos.write(srcTxt.getBytes());
IOUtils.closeQuietly(zos);
byte[] bytes = rstBao.toByteArray();
String base64comp = Base64.getEncoder().encodeToString(bytes);
System.out.println("Json String is " + srcTxt.toString().getBytes().length + " compressed " + bytes.length + " compressed Base64 " + base64comp.getBytes().length);
return base64comp;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
我已经检查了Base64输出,它似乎工作正常(粘贴)。此外,当我与Postman核对时,我得到一个二进制blob,如果我将响应保存为以.gz结尾的内容,则可以使用7-zip解包
在“设置”下,API网关二进制媒体类型已设置为/
但是我想让客户“看到”它是gzip,并在运行中解码它。但是,当我添加行时
returnObject.put("Content-Encoding", "gzip");
我得到{“message”:“internalserver error”},在AWS API日志中:由于配置错误,执行失败:Lambda代理响应格式错误
Lambda日志没有问题,因此它确实成功执行了,只是无法返回
我想我需要在API网关方面做更多的调整,有什么想法吗?这听起来好像API网关上的二进制支持设置配置不正确;API网关正在尝试解析来自lambda的响应,而不是将其直接传递给客户端 您可以在控制台中更新此设置: 在HTTP请求中添加带有有效负载内容类型的“Accept”头 接受:应用程序/gzip 同样在HTTP响应中,应该有指示响应内容类型的“Content Type”头 内容类型:应用程序/gzip
您的lambda将Base64编码的二进制数据返回到API网关。因此,为了解码数据,您的HTTP请求的Accept头和响应的Content-type头应该在那里。您能显示整个类吗?我希望看到
公共类XXXX实现……。
您实现的是什么接口?内容编码属于标题
,而不是返回对象
中的顶级键。看来你把这个放错地方是在构建一个错误的响应。迈克尔,你的评论成功了!但是我不能把它标记为答案?谢谢你的评论。我已经启用了这个选项,但我看到在我最初的问题中,这个句子已经被重命名。因此,为了清楚起见,我通过设置star/star(不带空格)启用了这个二进制媒体类型选项。