如何解决反序列化错误请问SDK

时间:2019-02-28 12:39:07

标签: java amazon-web-services aws-lambda aws-sdk objectmapper

我正在尝试从会话中转换JSON输出并将其映射到使用JAVA的ObjectMapper创建的类。当我在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 Output of properties under "riddleItem" during Session] 1

我知道我映射的值不是空的,因此我对所发生的事情完全一无所知,因为我对可能的问题提出了一些可能的想法。

1 个答案:

答案 0 :(得分:0)

我解决了这个问题,因为我意识到从JSON映射到类时,必须创建用于将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;
        }
} 

在使用多个构造函数(其中一个是参数的)时,必须声明一个空的构造函数。在某些情况下,如果不包含此类构造函数,则可能会引发错误,因此,为避免发生所述错误,可以说将构造函数添加为“虚拟”是必不可少的。