AWS Lex 从 lambda 函数接收到无效响应 - 无法构造 IntentResponse 实例
AWS Lex receives Invalid Response from lambda function - Can not construct instance of IntentResponse
在 eclipse AWS SDK 中使用 Java8,我创建并上传了一个 lambda 函数,该函数在实现我的 lex 意图时挂钩。
Lambda 没有问题接收 JSON 请求和解析。
然后,我格式化一个简单的 "Close" dialogAction 响应并发送回 lex,并从 lex 控制台的测试机器人页面收到以下错误:
An error has occurred: Received invalid response from Lambda:
Can not construct instance of IntentResponse:
no String-argument constructor/factory method to deserialize
from String value
('{"dialogAction
{"type":"Close","fulfillmentState":"Fulfilled","message":
{"contentType":"PlainText","content":"Thanks I got your info"}}}')
at [Source: "{\"dialogAction\":
{\"type\":\"Close\",\"fulfillmentState\":\"Fulfilled\",\"message\":
{\"contentType\":\"PlainText\",\"content\":\"Thanks I got your
info\"}}}";line: 1, column: 1]
格式似乎有问题(第 1 行,第 1 列),但我的 JSON 字符串看起来没问题。在 handleRequest java 函数中返回输出字符串之前,我将其写入 Cloudwatch 日志,其内容如下:
{
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled",
"message": {
"contentType": "PlainText",
"content": "Thanks I got your info"
}
}
}
我尝试过的事情:
- 删除不需要的消息元素
- 添加 non-required 属性,如 sessionAttributes,
响应卡等
- 删除双引号
- 用单引号代替双引号
- 硬编码json 来自文档中的示例响应格式消息
是否有隐藏在 http headers 级别的东西,或者 java8 是否对 JSON 做了一些不可见的事情?
不确定这是否是因为我正在使用 Java8,但是来自 RequestHandler class handleRequest 方法的 return 值 "String" 将不起作用.
是的,String 是一个对象,但是 Lex 端的构造函数期望 "Object"。在 handleRequest 方法中 returning 之前,我将 lex 响应 POJO 转换为字符串。那是我的错误。
我通过将 handleRequest 方法的 return 类型更改为 "Object" 而不是 "String". [=14= 来修复它]
public Object handleRequest(Object input, Context context)
而不是
public String handleRequest(Object input, Context context)
您还必须实施
public class LambdaFunctionHandler implements RequestHandler<Object, Object>
不是
public class LambdaFunctionHandler implements RequestHandler<Object, String>
这解决了我的问题。
在我的例子中,我遇到了完全相同的问题,并且能够通过创建特定的响应 POJO 类型并将此 POJO 用作 'handleRequest' 方法的 return 类型来解决它。例如。 BotResponse.java如下:
public class BotResponse implements Serializable{
private static final long serialVersionUID = 1L;
public DialogAction dialogAction = new DialogAction();
public DialogAction getDialogAction() {
return dialogAction;
}
public void setDialogAction(DialogAction dialogAction) {
this.dialogAction = dialogAction;
}
}
注意,为了安全起见,我还添加了 'implements Serializable'。可能这是一个矫枉过正。
不知道为什么,但对我来说 return 一个格式良好的 JSON String 对象即使在将 'handleRequest' 方法的 return 类型更改为 'Object' 之后也不起作用。
我知道这是一个老问题,但我认为这可能对其他人有所帮助
@Mattbob Solution 解决了我的问题,但他走在正确的道路上。最好的方法是使用一个 Response 对象,一个自定义响应对象,并使 lambda return 成为自定义响应对象。所以我去了文档并创建了一个看起来像响应格式的自定义对象
http://docs.aws.amazon.com/lex/latest/dg/lambda-input-response-format.html
在回答问题时,我无法在 SDK 中找到与响应对象匹配的对象,因此我不得不重新创建,但如果有人知道,请在下面评论
Class xxxxx implements RequestHandler<Object, AccountResponse> {
@Override
public AccountResponse handleRequest(Object input, Context context) {
}
}
Lambda 看起来有点像这样,只是填充 return 匹配响应结构的对象,错误就会消失。希望这有帮助。
每当我们从后端将对象返回给机器人时,请确保我们需要将内容类型与内容一起传递。但在这里我们传错了。所以我们需要像下面这样传递。它在 Node.js
let message = {
contentType: "PlainText",
content: 'Testing bot'
};
在 eclipse AWS SDK 中使用 Java8,我创建并上传了一个 lambda 函数,该函数在实现我的 lex 意图时挂钩。 Lambda 没有问题接收 JSON 请求和解析。 然后,我格式化一个简单的 "Close" dialogAction 响应并发送回 lex,并从 lex 控制台的测试机器人页面收到以下错误:
An error has occurred: Received invalid response from Lambda:
Can not construct instance of IntentResponse:
no String-argument constructor/factory method to deserialize
from String value
('{"dialogAction
{"type":"Close","fulfillmentState":"Fulfilled","message":
{"contentType":"PlainText","content":"Thanks I got your info"}}}')
at [Source: "{\"dialogAction\":
{\"type\":\"Close\",\"fulfillmentState\":\"Fulfilled\",\"message\":
{\"contentType\":\"PlainText\",\"content\":\"Thanks I got your
info\"}}}";line: 1, column: 1]
格式似乎有问题(第 1 行,第 1 列),但我的 JSON 字符串看起来没问题。在 handleRequest java 函数中返回输出字符串之前,我将其写入 Cloudwatch 日志,其内容如下:
{
"dialogAction": {
"type": "Close",
"fulfillmentState": "Fulfilled",
"message": {
"contentType": "PlainText",
"content": "Thanks I got your info"
}
}
}
我尝试过的事情:
- 删除不需要的消息元素
- 添加 non-required 属性,如 sessionAttributes, 响应卡等
- 删除双引号
- 用单引号代替双引号
- 硬编码json 来自文档中的示例响应格式消息
是否有隐藏在 http headers 级别的东西,或者 java8 是否对 JSON 做了一些不可见的事情?
不确定这是否是因为我正在使用 Java8,但是来自 RequestHandler class handleRequest 方法的 return 值 "String" 将不起作用. 是的,String 是一个对象,但是 Lex 端的构造函数期望 "Object"。在 handleRequest 方法中 returning 之前,我将 lex 响应 POJO 转换为字符串。那是我的错误。
我通过将 handleRequest 方法的 return 类型更改为 "Object" 而不是 "String". [=14= 来修复它]
public Object handleRequest(Object input, Context context)
而不是
public String handleRequest(Object input, Context context)
您还必须实施
public class LambdaFunctionHandler implements RequestHandler<Object, Object>
不是
public class LambdaFunctionHandler implements RequestHandler<Object, String>
这解决了我的问题。
在我的例子中,我遇到了完全相同的问题,并且能够通过创建特定的响应 POJO 类型并将此 POJO 用作 'handleRequest' 方法的 return 类型来解决它。例如。 BotResponse.java如下:
public class BotResponse implements Serializable{
private static final long serialVersionUID = 1L;
public DialogAction dialogAction = new DialogAction();
public DialogAction getDialogAction() {
return dialogAction;
}
public void setDialogAction(DialogAction dialogAction) {
this.dialogAction = dialogAction;
}
}
注意,为了安全起见,我还添加了 'implements Serializable'。可能这是一个矫枉过正。 不知道为什么,但对我来说 return 一个格式良好的 JSON String 对象即使在将 'handleRequest' 方法的 return 类型更改为 'Object' 之后也不起作用。
我知道这是一个老问题,但我认为这可能对其他人有所帮助
@Mattbob Solution 解决了我的问题,但他走在正确的道路上。最好的方法是使用一个 Response 对象,一个自定义响应对象,并使 lambda return 成为自定义响应对象。所以我去了文档并创建了一个看起来像响应格式的自定义对象
http://docs.aws.amazon.com/lex/latest/dg/lambda-input-response-format.html
在回答问题时,我无法在 SDK 中找到与响应对象匹配的对象,因此我不得不重新创建,但如果有人知道,请在下面评论
Class xxxxx implements RequestHandler<Object, AccountResponse> {
@Override
public AccountResponse handleRequest(Object input, Context context) {
} }
Lambda 看起来有点像这样,只是填充 return 匹配响应结构的对象,错误就会消失。希望这有帮助。
每当我们从后端将对象返回给机器人时,请确保我们需要将内容类型与内容一起传递。但在这里我们传错了。所以我们需要像下面这样传递。它在 Node.js
let message = {
contentType: "PlainText",
content: 'Testing bot'
};