簡體   English   中英

Symfony 信使 - 序列化消息中的對象

[英]Symfony messenger - serialize objects inside message

您好,我有一些應用程序正在向 Amazon SQS 隊列發送命令(消息)。 我有工作環境,我的命令在隊列中,但格式錯誤,如下所示:

{ "Messages": [ { "MessageId": "f3373e0d-b47e-2a46-51d8-38dc1ee8f07e", "ReceiptHandle": "dzpfgjsnrkwzmzzvzvddepxfpmxwipviybehoedxeolvbndunmceerozsanhwennjvgeunbsfxfxrrywrlkpeuifcnggnslzfgpkilnrwnlyegkcmlaowvcikxhsisujptanjrboedurezuzihngpfmsyxxzmtqghqyrfyycthxuamqnxblprvbbo", "MD5OfBody": "6a69c6c1e53718f891a409e5a9ba98a4", "Body": "O:36:\" Symfony\\Component\\Messenger\\Envelope\":2:{s:44:\"\0Symfony\\Component\\Messenger\\Envelope\0stamps\";a:1:{s:46:\"Symfony \\Component\\Messenger\\Stamp\\BusNameStamp\";a:1:{i:0;O:46:\"Symfony\\Component\\Messenger\\Stamp\\BusNameStamp\":1:{s :55:\"\0Symfony\\Component\\Messenger\\Stamp\\BusNameStamp\0busName\";s:21:\"messenger.bus.default\";}}}s:45:\"\0Symfony\ \Component\\Messenger\\Envelope\0message\";O:29:\"App\\Message\\CreatePostCommand\":1:{s:17:\"\0*\0postDataObject\";O:29: \"App\\DataObject\\PostDataObject\":5:{s:5:\"title\";s:11:\"Lorem ipsum\";s:7:\"摘錄\";s:27: \"Lorem ipsum dolor sit amet.\";s:7:\"content\";s:495:\"Donec laoreet maximus l acus,nec lacinia risus rutrum vitae。 Morbi tortor sapien, ornare in congue ac, aliquam quis felis。 Pellentesque venenatis, elit eget vehicula viverra, elit lacus congue ante, et accumsan est arcu vitae purus. Aliquam erat volutpat。 Nullam rhoncus risus augue, ut rhoncus leo sollicitudin sed. Maecenas fringilla, metus pretium tristique sodales, sem ante condimentum massa, a facilisis ligula lacus quis purus. Vestibulum pharetra rutrum velit,在 rutrum mi mollis vitae.\";s:6:\"author\";s:14:\"Bartosz Belski\";s:12:\"published_at\";N;}}} ", "Attributes": { "SenderId": "AIDAIT2UOQQY3AUEKVGXU", "SentTimestamp": "1649947456026" } } ] }

我懷疑這是序列化的錯誤。 我想將它作為 json 存儲在隊列中。 但我不知道如何做到這一點。

我的命令(消息):

final class CreatePostCommand
{
    protected PostDataObject $postDataObject;

    public function __construct(PostDataObject $postDataObject)
    {
        $this->postDataObject = $postDataObject;
    }

    public function getPostDataObject(): PostDataObject
    {
        return $this->postDataObject;
    }

    public function setPostDataObject(PostDataObject $postDataObject): self
    {
        $this->postDataObject = $postDataObject;

        return $this;
    }
}

我的 PostDataObject:

class PostDataObject extends DataObject
{
    public $title;

    public $excerpt;

    public $content;

    public $author;

    public $published_at;
}

有兩種方法可以實現__serialize__unserialize 使用它們以您想要的格式轉換為 json 或從 json 轉換:

final class CreatePostCommand
{
    protected PostDataObject $postDataObject;

    public function __serialize(): array
    {
        return ['title' => $this->postDataObject->title, 'excerpt' => $this->postDataObject->excerpt, ...];
    }

    public function __deserialize(array $data): void
    {
        $this->postDataObject->title = $data['title'];
        $this->postDataObject->excerpt = $data['excerpt'];
        ...
    }
}

我的解決方案與@Justinas 提出的有點不同。 我在本教程中為 symfony Messenger 創建了自己的序列化程序:

我的代碼:

namespace App\Message\Serializers;

use App\DataObject\PostDataObject;
use App\Message\CreatePostCommand;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;

class JsonDataObjectCommandSerializer implements SerializerInterface
{
    private \Symfony\Component\Serializer\SerializerInterface $serializer;

    public function __construct(\Symfony\Component\Serializer\SerializerInterface $serializer)
    {
        $this->serializer = $serializer;
    }

    public function decode(array $encodedEnvelope): Envelope
    {
        $body = $encodedEnvelope['body'];
        $headers = $encodedEnvelope['headers'];
        $data = json_decode($body, true);
        $message = new CreatePostCommand(new PostDataObject($data));
        $stamps = [];
        if (isset($headers['stamps'])) {
            $stamps = json_decode($headers['stamps']);
        }
        dump($data, $message, $stamps);
        return new Envelope($message, $stamps ?? []);
    }

    public function encode(Envelope $envelope): array
    {
        $message = $envelope->getMessage();
        if ($message instanceof CreatePostCommand) {
            $data = $message->getPostDataObject()->toArray();
        } else {
            throw new \Exception('Unsupported message class');
        }
        $allStamps = [];
        foreach ($envelope->all() as $stamps) {
            $allStamps = array_merge($allStamps, $stamps);
        }

        return [
            'body' => json_encode($data),
            'headers' => [
                'stamps' => $this->serializer->serialize($allStamps, 'json')
            ]
        ];
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM