【问题标题】:How configure JMSSerializer in Symfony to serialize custom class to/from int?如何在 Symfony 中配置 JMSSerializer 以将自定义类序列化到/从 int?
【发布时间】:2020-04-27 15:15:51
【问题描述】:

我正在开发一个基于 Symfony 3.4 的网络应用程序项目,该项目使用 JMSSerializer 将不同的自定义类序列化为 JSON 以将此数据发送到移动应用程序。

如何将自定义类序列化/反序列化到 int?


假设我们有以下类:

<?php

// AppBundle/Entity/...

class NotificationInfo {
    public $date;      // DateTime
    public $priority;  // Int 1-10
    public $repeates;  // Boolean

    public function toInt() {
        // Create a simple Int value
        //  date = 04/27/2020
        //  priority = 5
        //  repeats = true
        //  ==> int value = 4272020 5 1 = 427202051
    }

    public function __construnct($intValue) {
       // ==> Split int value into date, priority and repeats...
    }
}


class ToDoItem {
    public $title;
    public $tags;
    public $notificationInfo;
}


// AppBundle/Resources/config/serializer/Entiy.ToDoItem.yml
AppBundle\Entity\ToDoItem:
exclusion_policy: ALL
properties:
    title:
        type: string
        expose: true
    tags:
        type: string
        expose: true
    notificationInfo:
        type: integer
        expose: true

所以NotificationInfo 类也具有从int 创建它并将其序列化为in 的功能。如何告诉序列化程序它应该将$notificationInfo 的值序列化为int?

我可以改用以下内容:

    notificationInfo:
        type: AppBundle\Entity\NotificationInfo
        expose: true

但是在这种情况下,我需要配置NotificationInfo 的序列化,我只能指定哪个属性应该序列化为哪个值...


编辑:

这是我要创建的 JSON:

{
    "title": "Something ToDO",
    "tags": "some,tags",
    "notificationInfo": 427202051
}

这不是我要找的:

{
    "title": "Something ToDO",
    "tags": "some,tags",
    "notificationInfo": {
        "intValue": 427202051
    }
}

【问题讨论】:

  • 你试过JMS序列化器的VirtualProperty()方法吗?

标签: symfony jms-serializer


【解决方案1】:

经过大量挖掘,我找到了以下解决问题的方法:我添加了一个自定义序列化Handler,它告诉JMSSerializer 如何处理我的自定义类:

class NotificationInfoHandler implements SubscribingHandlerInterface {

    public static function getSubscribingMethods() {
        return [
            [
                'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                'format' => 'json',
                'type' => 'NotificationInfo',
                'method' => 'serializeNotificationInfoToJson',
            ],
            [
                'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
                'format' => 'json',
                'type' => 'NotificationInfo',
                'method' => 'deserializeNotificationInfoToJson',
            ],
        ;


    public function serializeNotificationInfoToJson(JsonSerializationVisitor $visitor, NotificationInfo $info, array $type, Context $context) {
        return $info->toInt();
    }

    public function deserializeNotificationInfoToJson(JsonDeserializationVisitor $visitor, $infoAsInt, array $type, Context $context) {
        return (is_int($infoAsInt) ? NotificationInfo::fromInt($infoAsInt) : NotificationInfo::emptyInfo());
    }

}

感谢autowire,自动添加处理程序并可在序列化器元数据中使用:

notificationInfo:
    type: NotificationInfo
    expose: true

【讨论】:

    【解决方案2】:

    你可以使用VirtualProperty 方法来添加你类的任何方法 进入json响应

    use JMS\Serializer\Annotation as Serializer;
    
    class NotificationInfo 
    {
        /**
         * @return int
         * @Serializer\VirtualProperty()
         * @Serializer\SerializedName("formatedLocation")
         */
        public function toInt()
        {
            return 4272020;
        }
    }
    

    【讨论】:

    • 谢谢,但是给NotificationInfo添加一个虚拟属性只会改变序列化对象的内容。但我希望将完整的NotificationInfo 对象/属性序列化为一个整数。我已经编辑了问题以展示差异。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 2016-02-28
    • 1970-01-01
    • 2019-09-06
    相关资源
    最近更新 更多