Надлежащая подпись метода Java handleRequest() для Amazon Echo/Alexa на Amazon Lambda?

Я пытаюсь создать функцию Amazon Lambda, реализованную на Java, для работы с Amazon Echo / Alexa. Я использую Eclipse Mars в качестве IDE.

Вот что мой LambdaFunctionHandler, который будет получать запросы от Alexa, выглядит так:

public class LambdaFunctionHandler implements RequestHandler<SpeechletRequestEnvelope, SpeechletResponse> {

    @Override
    public SpeechletResponse handleRequest(SpeechletRequestEnvelope input, Context context) {
        context.getLogger().log("Input: " + input);

        // TODO: implement your handler
        return null;
    }
}

Однако при попытке проверить это с помощью примера ввода JSON из Alexa я получаю сообщение об ошибке в Eclipse:

{"errorMessage": "Произошла ошибка при разборе JSON","errorType":"java.lang.RuntimeException","stackTrace":[],"ause":{"errorMessage":"Lcom/fastxml/jackson/databind/ObjectMapper;","errorType":"java.lang.NoClassDefFoundError","stackTrace":["java.lang.Class.getDeclaredFields0(Native Method)","java.lang.Class.privateGetDeclaredFields(Class.java:25) " "java.lang.Class.getDeclaredFields(Class.java:1916)","com.fasterxml.jackson.databind.introspect.AnnotatedClass._findFields(AnnotatedClass.java:689)","com.fasterxml.jackson.databind.introspect.AnnotatedClass.resolveFields(AnnotatedClass.java:470)" "com.fasterxml.jackson.databind.introspect.AnnotatedClass.fields(AnnotatedClass.java:282)","com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addFields(POJOPropertiesCollector.java:390)" "com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collect(POJOPropertiesCollector.java:243)","com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.collectProperties(BasicClassIntrospector.java:197)","com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forDeserialization(BasicClassIntrospector.java:110)","com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forDeserialization(BasicClassIntrospector.java:15)" "com.fasterxml.jackson.databind.DeserializationConfig.introspect(DeserializationConfig.java:703)","com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:330)","com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:265)" "com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:245)","com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:143)" "com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:439)","com.fasterxml.jackson.databind.ObjectReader._prefetchRootDeserializer(ObjectReader.java:. 1588)" "com.fasterxml.jackson.databind.ObjectReader (ObjectReader.java:185)","com.fasterxml.jackson.databind.ObjectMapper._newReader(ObjectMapper.java:558)"," ком.fasterxml.jackson.databind.ObjectMapper.reader(ObjectMapper.java:3098)"]," причина ": {" ErrorMessage":"com.fasterxml.jackson.databind.ObjectMapper" "ERRORTYPE":"java.lang.ClassNotFoundException" "StackTrace":["java.net.URLClassLoader.findClass(URLClassLoader.java:381)","java.lang.ClassLoader.loadClass(ClassLoader.java:424)","java.lang.ClassLoader.loadClass(ClassLoader.java:357)","java.lang.Class.getDeclaredFields0(Native Method)","java.lang.Class.privateGetDeclaredFields(Class.java:2583)","java.lang.Class.getDeclaredFields(Class.java:1916)" "com.fasterxml.jackson.databind.introspect.AnnotatedClass._findFields (AnnotatedClass.java:689)"," com.fasterxml.jackson.databind.introspect.AnnotatedClass.resolveFields (AnnotatedClass.java:470) " "com.fasterxml.jackson.databind.introspect.AnnotatedClass.fields (AnnotatedClass.java:282)"," ком. fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addFields (POJOPropertiesCollector.java:390) " "com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collect (POJOPropertiesCollector.java:243)"," com.fasterxml.jackson. databind.introspect.BasicClassIntrospector.collectProperties (BasicClassIntrospector.java:197) " "com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forDeserialization (BasicClassIntrospector.java:110)"," com.fasterxml.jackson.databind.introspect. BasicClassIntrospector.forDeserialization (BasicClassIntrospector.java:15) " "com.fasterxml.jackson.databind.DeserializationConfig.introspect (DeserializationConfig.java:703)"," com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer (DeserializerCache. Java: 330) " "com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:265)","com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:245)"" ком.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer (DeserializerCache.java:143) " "com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:439)","com.fasterxml.jackson.databind.ObjectReader._prefetchRootDeserializer(ObjectReader.java:1588)" "com.fasterxml.jackson.databind.ObjectReader (ObjectReader.java:185)"," com.fasterxml.jackson.databind.ObjectMapper._newReader (ObjectMapper.java.:558)","com.fasterxml.jackson.databind.ObjectMapper.reader(ObjectMapper.java:3098)"]}}}

Вот мой ввод JSON (взят из примера TestColors онлайн):

{
  "session": {
    "new": false,
    "sessionId": "session1234",
    "attributes": {},
    "user": {
      "userId": null
    },
    "application": {
      "applicationId": "amzn1.echo-sdk-ams.app.[unique-value-here]"
    }
  },
  "version": "1.0",
  "request": {
    "intent": {
      "slots": {
        "Color": {
          "name": "Color",
          "value": "red"
        }
      },
      "name": "MyColorIsIntent"
    },
    "type": "IntentRequest",
    "requestId": "request5678"
  }
}

Итак, судя по всему Амазонка SpeechletRequestEnvelope не правильный входной класс для handleRequest(),

Какова правильная подпись метода для handleRequest() получать запросы от Alexa?

Я не могу найти пример Java для Amazon Lambda, который работает с Alexa/Echo.

2 ответа

Решение

Вот полный рабочий пример:

public class LambdaFunctionHandler implements RequestStreamHandler {

    @Override
    public void handleRequest(InputStream inputStream, OutputStream output, Context context) throws IOException {
        byte serializedSpeechletRequest[] = IOUtils.toByteArray(inputStream);
        SpeechletRequestEnvelope requestEnvelope = SpeechletRequestEnvelope.fromJson(serializedSpeechletRequest);
        SpeechletRequest speechletRequest = requestEnvelope.getRequest();

        if (speechletRequest instanceof IntentRequest) {
            IntentRequest ir = (IntentRequest) speechletRequest;
            String outString = "IntentRequest name: " + ir.getIntent().getName();
            context.getLogger().log(outString);
            output.write(outString.getBytes());
        }
    }
}

Обратите внимание, что этот класс реализует RequestStreamHandlerНЕ RequestHandler,

Используя входной JSON из вопроса, output.write(outString.getBytes()) приведет к выводу на консоль Eclipse AWS Lambda:

==================== ВЫХОД ФУНКЦИИ ====================

IntentRequest name: MyColorIsIntent

...в то время как context.getLogger().log(outString); результаты в той же строке записываются в онлайн-консоли Amazon Lambda.

Вы также должны убедиться, что у вас есть папка /lib в вашем проекте, и следующие JAR должны быть включены:

  • Обще-кодек-1.6.jar
  • Обще-lang3-3.x.jar
  • ДЖЕКСОН-аннотаций-2.3.2.jar
  • ДЖЕКСОН-ядро-2.3.2.jar
  • ДЖЕКСОН-DataBind-2.3.2.jar
  • JakartaCommons-IO-2.4.jar
  • Joda-времени 2.3.jar
  • log4j.1.2.17.jar
  • сервлет-апи-3.0.jar
  • SLF4J-апи-1.7.4.jar
  • SLF4J-log4j12-1.7.4.jar
  • Alexa-навыки-набор-1.0.jar

Эти JAR-файлы могут быть загружены из Maven Central или из "сторонней" подпапки в AlexaSkillsKit.zip.

В Eclipse вам нужно обновить проект, чтобы он увидел файлы JAR в /lib каталог (просто нажмите F5), а затем добавьте JAR-файлы в путь сборки Java:

  1. Щелкните правой кнопкой мыши на корне проекта Lambda в Eclipse.
  2. Нажмите "Свойства"
  3. Выберите "Путь сборки Java"
  4. Выберите вкладку "Библиотеки"
  5. Нажмите "Добавить JAR"
  6. Перейдите к "lib"
  7. Выберите все JAR-файлы в папке "lib" и нажимайте "Ok", пока не вернетесь к основному экрану Eclipse.

Спасибо @jephers за указатель на этот замечательный урок на Github, где я собрал много всего этого из:

https://github.com/jjaquinta/EchoProofOfConcepts/tree/master/jo.echo.lambda

Я расширяю jo.echo.lambda.utils.SpeechletLambda ( https://github.com/jjaquinta/EchoProofOfConcepts/blob/master/jo.echo.lambda/jo/echo/lambda/utils/SpeechletLambda.java), и это работает для мне:

@Override
public void handleRequest(InputStream inputStream,
        OutputStream outputStream, Context context) throws IOException
{
    super.handleRequest(inputStream, outputStream, context);
}

Надеюсь это поможет

Другие вопросы по тегам