【问题标题】:AWS Lex receives Invalid Response from lambda function - Can not construct instance of IntentResponseAWS Lex 从 lambda 函数接收无效响应 - 无法构造 IntentResponse 的实例
【发布时间】:2017-07-06 03:01:37
【问题描述】:

在 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, 响应卡等
  • 去掉双引号
  • 用单引号代替双引号
  • 从文档中的示例响应格式消息硬编码 json

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

【问题讨论】:

  • 这个帖子似乎在解决同样的问题:stackoverflow.com/questions/44756575/…
  • 类似,是的,但我的问题是 Lex 处理来自 Lambda 的响应,而不是 Lambda 处理来自 Lex 的请求(我能够做到)。

标签: aws-lambda amazon-lex


【解决方案1】:

不确定这是否是因为我使用的是 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>

这解决了我的问题。

【讨论】:

    【解决方案2】:

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

    注意,为了更安全,我还添加了“实现可序列化”。大概是矫枉过正了。 不知道为什么,但对我来说,即使在将“handleRequest”方法的返回类型更改为“对象”之后,返回格式良好的 JSON 字符串对象也不起作用。

    【讨论】:

      【解决方案3】:

      我知道这是一个老问题,但我认为这可能会有所帮助

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-11-05
          • 2018-02-28
          • 2021-10-23
          • 1970-01-01
          • 2021-06-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多