【问题标题】:Dynamic JMS Serializer types动态 JMS 序列化程序类型
【发布时间】:2017-06-12 13:26:59
【问题描述】:

是否可以在同一个属性上拥有一个类,具有 2 种类型(1 种用于序列化,1 种用于反序列化)?

例如,我使用的 API 允许我将地址作为字符串发送,并且我接收到与对象相同的地址。像这样:

请求:

{
  "address": "12 rue rivoli, 75001 Paris"
}

回应

{
  "address": {
    "street": "12 Rue de Rivoli",
    "postcode": "75004",
    "city": "Paris",
    "country": "France"
  }
}

【问题讨论】:

    标签: symfony jmsserializerbundle jms-serializer


    【解决方案1】:

    是的,您可以使用 @Accessor Annotation Tag of the JmsSerializer 实现此目的:

    这个注解可以定义在一个属性上来指定 应该调用哪个公共方法来检索或设置 给定的属性:

    在您的实体中,这可能如下所示:

    # AppBundle/Entity/User
    <?php
    use JMS\Serializer\Annotation\Accessor;
    
    class User
    {
    
    
        /** 
         * @var AppBundle\Entity\Address
         * 
         * @Accessor(getter="getAddressAsString",setter="setAddress") 
         */
        private $address;
    
        // ...
        public function getAddressAsString()
        {
            return sprintf('%s, %s %s', $this->address->getStreet(), $this->address->Postcode(), $this->address->getCity()),
        }
    
        public function setAddress(Address $address)
        {
            $this->address = $address;
        }
    }
    

    【讨论】:

    • 我有这个错误:You must define a type for User::$address.
    • 您是否尝试在User::$address 属性上添加以下注释:@JMS\Type("...")
    • 这里的阻碍是你不能为序列化/反序列化定义不同的类型。我目前正在努力解决类似的问题,到目前为止没有找到解决方案:(
    【解决方案2】:

    所以,这是一个对我有用的解决方案:

    1. 定义一个你将把字段序列化成的类型,即

      /**

      • @var 字符串
        • @Type("字符串") */ 私人 $address;
    2. serializer.pre_deserialize 事件上实现订阅者/侦听器,即

      class MyPreDeserializationSubscriber implements EventSubscriberInterface
      {
          public static function getSubscribedEvents()
      {
          return [
              [
                  'event' => 'serializer.pre_deserialize',
                  'method' => 'onPreDeserialize',
                  'class' => Video::class,
                  'format' => 'json',
              ]
          ];
      }
      
      public function onPreDeserialize(PreDeserializeEvent $event)
      {
          $data = $event->getData();
          $data['address'] = implode(', ', $data['address']);
          $event->setData($data);
      }
      

      }

    【讨论】:

      猜你喜欢
      • 2017-05-16
      • 1970-01-01
      • 1970-01-01
      • 2016-07-25
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      相关资源
      最近更新 更多