Как решить ошибку десериализации спросите SDK - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь преобразовать вывод JSON из моего сеанса и сопоставить его с классом, который я создал с помощью ObjectMapper JAVA.Когда я запускаю свои тесты на Lambda, я получаю ошибку десериализации:

Deserialization error: com.amazon.ask.exception.AskSdkException
com.amazon.ask.exception.AskSdkException: Deserialization error
    at com.amazon.ask.util.impl.JacksonJsonUnmarshaller.unmarshall(JacksonJsonUnmarshaller.java:50)
    at com.amazon.ask.impl.AbstractSkill.execute(AbstractSkill.java:44)
    at com.amazon.ask.AlexaSkill.execute(AlexaSkill.java:22)
    at com.amazon.ask.SkillStreamHandler.handleRequest(SkillStreamHandler.java:71)
Caused by: com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'AnswerIntent' as a subtype of [simple type, class com.amazon.ask.model.Request]: known type ids = [Alexa.Presentation.APL.UserEvent, AlexaHouseholdListEvent.ItemsCreated, AlexaHouseholdListEvent.ItemsDeleted, AlexaHouseholdListEvent.ItemsUpdated, AlexaHouseholdListEvent.ListCreated, AlexaHouseholdListEvent.ListDeleted, AlexaHouseholdListEvent.ListUpdated, AlexaSkillEvent.SkillAccountLinked, AlexaSkillEvent.SkillDisabled, AlexaSkillEvent.SkillEnabled, AlexaSkillEvent.SkillPermissionAccepted, AlexaSkillEvent.SkillPermissionChanged, AudioPlayer.PlaybackFailed, AudioPlayer.PlaybackFinished, AudioPlayer.PlaybackNearlyFinished, AudioPlayer.PlaybackStarted, AudioPlayer.PlaybackStopped, Connections.Request, Connections.Response, Display.ElementSelected, GameEngine.InputHandlerEvent, IntentRequest, LaunchRequest, Messaging.MessageReceived, PlaybackController.NextCommandIssued, PlaybackController.PauseCommandIssued, PlaybackController.PlayCommandIssued, PlaybackController.PreviousCommandIssued, SessionEndedRequest, System.ExceptionEncountered] (for POJO property 'request')
 at [Source: UNKNOWN; line: -1, column: -1] (through reference chain: com.amazon.ask.model.RequestEnvelope$Builder["request"])
    at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43)
    at com.fasterxml.jackson.databind.DeserializationContext.invalidTypeIdException(DeserializationContext.java:1628)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownTypeId(DeserializationContext.java:1186)
    at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._handleUnknownTypeId(TypeDeserializerBase.java:291)
    at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._findDeserializer(TypeDeserializerBase.java:162)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:113)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:97)
    at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserializeWithType(AbstractDeserializer.java:254)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeSetAndReturn(MethodProperty.java:151)
    at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.vanillaDeserialize(BuilderBasedDeserializer.java:269)
    at com.fasterxml.jackson.databind.deser.BuilderBasedDeserializer.deserialize(BuilderBasedDeserializer.java:193)
    at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:3972)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2264)
    at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:2746)
    at com.amazon.ask.util.impl.JacksonJsonUnmarshaller.unmarshall(JacksonJsonUnmarshaller.java:48)
    ... 3 more

Я проверил, чтобы убедиться, что моя переменная "riddleItem" не равна нулю.Значения JSON сопоставляются с классом Person, который просто возвращает свойства человека.Код показан ниже, и я выделил строку, в которой происходит ошибка:

public Optional<Response> handle(HandlerInput input) {

        Map<String, Object> sessionAttributes = input.getAttributesManager().getSessionAttributes();
        System.out.println("This a FIRST debug");
        LOG.debug("This a FIRST debug");

        boolean correctAnswer;
        String speechText = null, response;
        System.out.println("This a SECOND debug");


        Map<String, String> riddleItem = (LinkedHashMap<String, String>)sessionAttributes.get(Attributes.RIDDLE_ITEM_KEY);
        Person person;

//        System.out.println("riddleItem " + riddleItem);
        if(riddleItem != null)
        {
            person = MAPPER.convertValue(riddleItem, Person.class); // ERROR OCCURS ON THIS LINE
        }
        System.out.println("This a THIRD debug");

        PersonProperty personProperty = PersonProperty.valueOf((String) sessionAttributes.get(Attributes.RIDDLE_PROPERTY_KEY));
        int counter = (int) sessionAttributes.get(Attributes.COUNTER_KEY);
        int riddleGameScore = (int) sessionAttributes.get(Attributes.RIDDLE_SCORE_KEY);
        System.out.println("This a FOURTH debug");

        IntentRequest intentRequest = (IntentRequest) input.getRequestEnvelope().getRequest();
        correctAnswer = compareSlots(intentRequest.getIntent().getSlots(), getPropertyOfPerson(personProperty, person));
        System.out.println("This a FIFTH debug " + correctAnswer);

        if(correctAnswer)
        {
            riddleGameScore++;
            response = getSpeechExpressionCon(true);
            System.out.println("This a SIXTH debug " + response);

            sessionAttributes.put(Attributes.RIDDLE_SCORE_KEY, riddleGameScore);
        }
        else
        {
            response = getSpeechExpressionCon(false);
            System.out.println("This a SEVENTH debug " + response);

        }

        AnswerIntentHandler setup = new AnswerIntentHandler();
//
        if(riddle.getAnswer() != null)
        {
            speechText = "Hello " + riddle.getAnswer();
        }

        return input.getResponseBuilder()
                .withSimpleCard("RiddleSession", speechText)
                .withSpeech(speechText)
                .withShouldEndSession(true)
                .build();
}

[Json Вывод свойств в разделе "riddleItem" во время сеанса] 1

Я знаю, что отображаемые значения не пусты, поэтому у меня полная потеря идей относительно того, что происходит, так как мне не хватает возможных идей относительно того, в чем может быть проблемабыть.

1 Ответ

0 голосов
/ 01 марта 2019

Я решил эту проблему, когда понял, что при отображении из JSON в класс необходимо создать методы (методы 'set') для назначения значений JSON переменным в классе.Пример структуры, например:

public class State {
    public State() {}

        public State(String name, String abbreviation, String capital, String statehoodYear, String statehoodOrder) {
            this.name = name;
            this.abbreviation = abbreviation;
            this.capital = capital;
            this.statehoodYear = statehoodYear;
            this.statehoodOrder = statehoodOrder;
        }

        public String getName() {
            return name;
        }

        public String getAbbreviation() {
            return abbreviation;
        }

        public String getCapital() {
            return capital;
        }

        public String getStatehoodYear() { return statehoodYear; }

        public String getStatehoodOrder() {
            return statehoodOrder;
        }

        public void setName(String name) {
            this.name = name;
        }

        public void setAbbreviation(String abbreviation) {
            this.abbreviation = abbreviation;
        }

        public void setCapital(String capital) {
            this.capital = capital;
        }

        public void setStatehoodYear(String statehoodYear) {
            this.statehoodYear = statehoodYear;
        }

        public void setStatehoodOrder(String statehoodOrder) {
            this.statehoodOrder = statehoodOrder;
        }
} 

Объявление пустого конструктора необходимо при использовании нескольких конструкторов, где один является параметрическим.В некоторых случаях без включения такого конструктора может выдаваться ошибка, поэтому, чтобы избежать возможности указанной ошибки, добавление конструктора в качестве «фиктивного», так сказать, является существенным.

...