第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

Jackson反序列化SNS消息錯(cuò)誤MismatchedInputException

Jackson反序列化SNS消息錯(cuò)誤MismatchedInputException

叮當(dāng)貓咪 2023-09-20 15:21:37
我正在編寫一個(gè)通過(guò) SNS HTTP 請(qǐng)求處理來(lái)自 Amazon Simple Email Service 的回調(diào)的功能。我想將亞馬遜提供的消息解析為本地對(duì)象結(jié)構(gòu)。問(wèn)題是 SNS 將 JSON 消息包裝成字符串,并且 Jackson 無(wú)法解析它。我收到錯(cuò)誤:com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `xxx.email.domain.aws.ses.Notification` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"notificationType":"Delivery","mail":{"timestamp":"2019-10-02T14:43:14.570Z" ... next values of the message ... }}')來(lái)自 SNS 的整條消息如下所示: {  "Type" : "Notification",  "MessageId" : "4944xxxx-711d-57d4-91b8-8215cxxxxx",  "TopicArn" : "arn:aws:sns:eu-west-1:...",  "Message" : "{\"notificationType\":\"Delivery\",\"mail\":{\"timestamp\":\"2019-10-02T14:43:14.570Z\", ... next values of the message ... },\"delivery\":{\"timestamp\":\"2019-10-02T14:43:16.030Z\", ... next values of the message ... }}",  "Timestamp" : "2019-10-02T14:43:16.062Z",  "SignatureVersion" : "1",  "Signature" : "signature base64",  "SigningCertURL" : "cert url",  "UnsubscribeURL" : "unsubscribe url"}我的實(shí)際本地結(jié)構(gòu)如下所示:@Data@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)public class MessageWrapper {    private String type;    private String messageId;    private String topicArn;    private Notification message;    private Date timestamp;    private String signatureVersion;    private String signature;    private String signingCertURL;    private String unsubscribeURL;}@Datapublic class Notification {    private String notificationType;    private Mail mail;}@Datapublic class Mail {    private String messageId;    private String source;    private String sourceArn;    private String sourceIp;    private String sendingAccountId;    private String[] destination;}我正在尋找某種方法來(lái)告訴 JacksonMessage應(yīng)該從字符串中提取并視為普通的 JSON。編輯反序列化private MessageWrapper deserializeMessage(String message) throws IOException {    return new ObjectMapper().readValue(message, MessageWrapper.class);}
查看完整描述

2 回答

?
天涯盡頭無(wú)女友

TA貢獻(xiàn)1831條經(jīng)驗(yàn) 獲得超9個(gè)贊

我認(rèn)為要解決這個(gè)問(wèn)題,您需要一個(gè)用于類Notification中字段的自定義反序列化器MessageWrapper以及一個(gè)用于類Mail中字段的自定義反序列化器Notification,如下所示:


public class NotificationDeserializer extends JsonDeserializer<Notification> {

    @Override

    public Notification deserialize(JsonParser p, DeserializationContext ctxt)

            throws IOException, JsonProcessingException {

        String text = p.getText();


        return new ObjectMapper().readValue(text, Notification.class);

    }

}


public class MailDeserializer extends JsonDeserializer<Mail> {

    @Override

    public Mail deserialize(JsonParser p, DeserializationContext ctxt)

            throws IOException, JsonProcessingException {

        String text = p.getText();


        return new ObjectMapper().readValue(text, Mail.class); 

    }

}

在您的類上添加一些注釋,如下所示:


@Data

@JsonNaming(PropertyNamingStrategy.UpperCamelCaseStrategy.class)

public class MessageWrapper {

    private String type;

    private String messageId;

    private String topicArn;

    @JsonDeserialize(using = NotificationDeserializer.class)

    private Notification message;

    private Date timestamp;

    private String signatureVersion;

    private String signature;

    private String signingCertURL;

    private String unsubscribeURL;

}


@Data

public class Notification {

    private String notificationType;

    @JsonDeserialize(using = MailDeserializer.class)

    private Mail mail;

}


@Data

public class Mail {

    private String messageId;

    private String source;

    private String sourceArn;

    private String sourceIp;

    private String sendingAccountId;

    private String[] destination;

}

編輯1


實(shí)際上并不MailDeserializer需要。獨(dú)自NotificationDeserializer解決這個(gè)問(wèn)題。


編輯2


在自定義解串器中使用新的ObjectMapper是必須的。


查看完整回答
反對(duì) 回復(fù) 2023-09-20
?
慕雪6442864

TA貢獻(xiàn)1812條經(jīng)驗(yàn) 獲得超5個(gè)贊

messageproperty 的類型為 type Notification,但Jackson預(yù)期JSON Object不是string value。在這種情況下,您可以創(chuàng)建自定義反序列化器或通過(guò)某種環(huán)回實(shí)現(xiàn)來(lái)實(shí)現(xiàn)通用解決方案。如果給定的有效負(fù)載不是 aJSON Object將其讀取為 aString并使用 this 再次調(diào)用反序列化String。


為了避免StackOverflowError您需要使用另一個(gè)實(shí)例ObjectMapper或使用BeanDeserializerModifier保留BeanDeserializer實(shí)例并在遇到的地方使用它JSON Object。簡(jiǎn)單的例子如下所示:


import com.fasterxml.jackson.core.JsonParser;

import com.fasterxml.jackson.core.JsonToken;

import com.fasterxml.jackson.databind.BeanDescription;

import com.fasterxml.jackson.databind.DeserializationConfig;

import com.fasterxml.jackson.databind.DeserializationContext;

import com.fasterxml.jackson.databind.DeserializationFeature;

import com.fasterxml.jackson.databind.JsonDeserializer;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.PropertyNamingStrategy;

import com.fasterxml.jackson.databind.annotation.JsonNaming;

import com.fasterxml.jackson.databind.deser.BeanDeserializer;

import com.fasterxml.jackson.databind.deser.BeanDeserializerBase;

import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier;

import com.fasterxml.jackson.databind.module.SimpleModule;

import com.fasterxml.jackson.databind.node.TextNode;

import lombok.Data;

import lombok.ToString;


import java.io.File;

import java.io.IOException;

import java.util.Collections;

import java.util.Date;

import java.util.Objects;

import java.util.Set;


public class JsonApp {


    public static void main(String[] args) throws Exception {

        File jsonFile = new File("./resource/test.json").getAbsoluteFile();


        SimpleModule loopBackModule = new SimpleModule();

        loopBackModule.setDeserializerModifier(new LoopBackBeanDeserializerModifier(Collections.singleton(Notification.class)));


        ObjectMapper mapper = new ObjectMapper();

        mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        mapper.registerModule(loopBackModule);


        MessageWrapper wrapper = mapper.readValue(jsonFile, MessageWrapper.class);

        System.out.println(wrapper.getMessage());

    }

}


class LoopBackBeanDeserializerModifier extends BeanDeserializerModifier {


    private final Set<Class> allowedClasses;


    LoopBackBeanDeserializerModifier(Set<Class> allowedClasses) {

        this.allowedClasses = Objects.requireNonNull(allowedClasses);

    }


    @Override

    public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {

        if (allowedClasses.contains(beanDesc.getBeanClass())) {

            return new LoopBackBeanDeserializer<>((BeanDeserializerBase) deserializer);

        }

        return deserializer;

    }

}


class LoopBackBeanDeserializer<T> extends BeanDeserializer {


    private final BeanDeserializerBase baseDeserializer;


    protected LoopBackBeanDeserializer(BeanDeserializerBase src) {

        super(src);

        this.baseDeserializer = src;

    }


    @Override

    public T deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {

        // if first token is VALUE_STRING we should read it as String and

        // run deserialization process again based on this String.

        if (p.currentToken() == JsonToken.VALUE_STRING) {

            return (T) ((ObjectMapper) p.getCodec()).readValue(p.getText(), _valueClass);

        }


        // vanilla bean deserialization

        return (T) baseDeserializer.deserialize(p, ctxt);

    }

POJO型號(hào)是一樣的。您只需要列出您期望某些問(wèn)題和loop-back機(jī)制適用于它們的類。


查看完整回答
反對(duì) 回復(fù) 2023-09-20
  • 2 回答
  • 0 關(guān)注
  • 533 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)