AWS Lex从lambda函数接收无效响应 - 无法构造IntentResponse的实例

时间:2017-07-06 03:01:38

标签: aws-lambda amazon-lex

在eclipse AWS SDK中使用Java8,我创建并上传了一个lambda函数,该函数在满足我的lex意图时被挂钩。 Lambda在接收JSON请求和解析时没有问题。 然后,我格式化一个简单的“关闭”dialogAction响应并发送回lex并从lex控制台的Test Bot页面接收以下错误:

    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"
        }
    }
}

我尝试过的事情:

  • 删除不需要的消息元素
  • 添加sessionAttributes等非必需属性, responseCard等
  • 删除双引号
  • 用单引号替换双引号
  • 来自文档中的样本响应格式消息的硬编码json

在http标题级别是否隐藏了某些内容,或者java8是否对JSON进行了一些不可见的操作?

4 个答案:

答案 0 :(得分:2)

不确定这是因为我是否使用Java8,但RequestHandler类handleRequest方法的返回值“String”将不起作用。 是的,String是一个对象,但Lex方面的构造函数期待一个“对象”。我在将lex响应POJO转换为String之前将其转换为handleRequest方法。那是我的错。

我通过将handleRequest方法的返回类型更改为“Object”而不是“String”来修复它。

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>

这解决了我的问题。

答案 1 :(得分:1)

在我的情况下,我遇到了完全相同的问题,并且能够通过创建特定的响应POJO类型并使用此POJO作为&#39; handleRequest&#39;的返回类型来修复它。方法。例如。 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;
    }
}

注意,我还添加了&#39;实现Serializable&#39;只是为了更加安全。可能这是一种矫枉过正。 不知道为什么但是对于我来说,即使在更改了&#39; handleRequest&#39;的返回类型之后,返回格式良好的JSON String对象也无效。方法&#39;对象&#39;。

答案 2 :(得分:0)

我知道这是一个老问题,但是认为这可能有助于其他人

@Mattbob解决方案dint解决了我的问题,但他正走在正确的道路上。最好的方法是使用Response对象,自定义响应对象,并使lambda返回自定义响应对象。所以我去了文档并创建了一个自定义对象,看起来像这里的响应格式

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看起来有点像这样,只需填充并返回对象以匹配响应结构,错误消失。希望这会有所帮助。

答案 3 :(得分:0)

每当我们从后端将对象返回给机器人时,请确保我们需要将内容类型与内容一起传递。但是我们在这里错了。所以我们需要像下面这样通过。它在Node.js中

 let message = {
        contentType: "PlainText",
        content: 'Testing bot'
      };