3

I'm trying to create an Amazon Lambda function implemented in Java to work with Amazon Echo/Alexa. I'm using Eclipse Mars as the IDE.

Here's what my LambdaFunctionHandler, which will receive the requests from Alexa, looks like:

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

However, when trying to test this with sample JSON input from Alexa, I get the error in Eclipse:

{"errorMessage":"An error occurred during JSON parsing","errorType":"java.lang.RuntimeException","stackTrace":[],"cause":{"errorMessage":"Lcom/fasterxml/jackson/databind/ObjectMapper;","errorType":"java.lang.NoClassDefFoundError","stackTrace":["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)","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)","com.fasterxml.jackson.databind.ObjectMapper.reader(ObjectMapper.java:3098)"],"cause":{"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)","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)","com.fasterxml.jackson.databind.ObjectMapper.reader(ObjectMapper.java:3098)"]}}}

Here's my JSON input (taken from the TestColors example online):

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

So, apparently Amazon SpeechletRequestEnvelope isn't the correct input class for handleRequest().

What is the correct method signature for handleRequest() to receive requests from Alexa?

I can't find a Java example for Amazon Lambda that works with Alexa/Echo.

4

2 に答える 2

6

完全な動作例を次に示します。

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は NOTを実装していることに注意してくださいRequestHandler

質問からの入力 JSON を使用するoutput.write(outString.getBytes())と、Eclipse AWS Lambda コンソールに出力されます。

==================== 関数の出力 ====================

IntentRequest 名: MyColorIsIntent

...whilecontext.getLogger().log(outString);を実行すると、同じ行がオンラインの Amazon Lambda コンソールに書き込まれます。

また、プロジェクトにフォルダーがあることを確認する必要が/libあり、次の JAR を含める必要があります。

  • commons-codec-1.6.jar
  • commons-lang3-3.x.jar
  • ジャクソン-注釈-2.3.2.jar
  • ジャクソン-コア-2.3.2.jar
  • jackson-databind-2.3.2.jar
  • JakartaCommons-IO-2.4.jar
  • joda-time-2.3.jar
  • log4j.1.2.17.jar
  • サーブレット-api-3.0.jar
  • slf4j-api-1.7.4.jar
  • slf4j-log4j12-1.7.4.jar
  • alexa-skills-kit-1.0.jar

これらの JAR は、 Maven Centralから、またはAlexaSkillsKit.zipの「サードパーティ」サブフォルダーからダウンロードできます。

Eclipse では、ディレクトリ内の JAR ファイルが表示されるようにプロジェクトを更新し/lib(F5 キーを押すだけ)、JAR を Java ビルド パスに追加する必要があります。

  1. Eclipse で Lambda プロジェクトのルートを右クリックします。
  2. 「プロパティ」をクリック
  3. 「Javaビルドパス」を選択
  4. 「ライブラリ」タブを選択します
  5. 「JARを追加」をクリック
  6. 「lib」を参照します
  7. 「lib」フォルダー内のすべての JAR を選択し、Eclipse のメイン画面に戻るまで「OK」をクリックします。

Github のこの素晴らしいチュートリアルへのポインタを提供してくれた @jephers に感謝します。

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

于 2015-08-26T02:55:55.333 に答える
1

私は 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);
}

お役に立てれば

于 2015-08-25T13:19:45.640 に答える