1

在 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

4 回答 4

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>

这解决了我的问题。

于 2017-07-06T16:23:44.463 回答
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 字符串对象也不起作用。

于 2017-08-21T17:00:16.803 回答
0

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

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

于 2017-08-27T21:59:26.793 回答
0

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

 let message = {
        contentType: "PlainText",
        content: 'Testing bot'
      }; 
于 2020-10-21T13:24:03.497 回答