JMSSerializerBundle - 保留关系名称

时间:2015-08-26 11:18:31

标签: symfony jmsserializerbundle

我正在使用Symfony2和JMSSerializerBundle。我最后一个新的=)在这种情况下我该怎么办:

我有图像模型。它包含一些字段,但主要字段是" name"。另外,我有一些模型,它们参考了Image模型。例如用户和应用程序。用户模型具有OneToOne字段" avatar",并且Application具有OneToOne字段" icon"。现在,我想序列化User实例并获得类似

的内容
{
     ...,
     "avatar": "http://example.com/my/image/path/image_name.png",
     ....
}

另外,我想序列化Application并获取

{
    ...,
    "icon": "http://example.com/my/image/path/another_image_name.png",
    ...
}

我在User :: avatar和Application :: icon字段上使用@Inline注释将Image对象(与此字段相关)减少为单个标量值(仅图像"名称"需要) 。此外,我的图像模型具有ExclusionPolicy(" all"),并且仅公开" name"领域。目前,JMSSerializer输出为

(For User instance)
{
    ...,
    "name": "http://example.com/my/image/path/image_name.png",
    ...
}

(For Application instance)
{
    ...,
    "name": "http://example.com/my/image/path/another_image_name.png",
    ...
}

问题是:如何让JMSSerializer保留" avatar"和" icon"序列化数组中的键而不是" name"?

1 个答案:

答案 0 :(得分:1)

最后,我找到了解决方案。在我看来,它不是很优雅和美丽,但它有效。

  1. 我告诉JMSSerializer,User :: avatar和Application :: icon是Images。为此,我使用了注释@Type("Image")

    //src\AppBundle\Entity\User.php
    //...        
    /**
     * @var integer
     *
     * @ORM\OneToOne(targetEntity="AppBundle\Entity\Image")
     * @ORM\JoinColumn(name="avatar", referencedColumnName="id")
     *
     * @JMS\Expose()
     * @JMS\Type("Image")
     */
    private $avatar;
    //...
    
    //src\AppBundle\Entity\Application.php
    //...
    /**
     * @var integer
     *
     * @ORM\OneToOne(targetEntity="AppBundle\Entity\Image")
     * @ORM\JoinColumn(name="icon", referencedColumnName="id")
     *
     * @JMS\Expose()
     * @JMS\Type("Image")
     */
    private $icon;
    //...
    
  2. 我实现了处理程序,它将类型为Image的对象序列化为json

    <?php
    //src\AppBundle\Serializer\ImageTypeHandler.php
    namespace AppBundle\Serializer;
    
    
    use AppBundle\Entity\Image;
    use JMS\Serializer\Context;
    use JMS\Serializer\GraphNavigator;
    use JMS\Serializer\Handler\SubscribingHandlerInterface;
    use JMS\Serializer\JsonSerializationVisitor;
    use Symfony\Component\HttpFoundation\Request;
    
    class ImageTypeHandler implements SubscribingHandlerInterface
    {
        private $request;
    
        public function __construct(Request $request) {
            $this->request = $request;
    
        }
    
        static public function getSubscribingMethods()
        {
            return [
                [
                    'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
                    'format' => 'json',
                    'type' => 'Image',
                    'method' => 'serializeImageToWebPath'
                ]
            ];
        }
    
        public function serializeImageToWebPath(JsonSerializationVisitor $visitor, Image $image = null, array $type, Context $context)
        {
            $path = $image ? "http://" . $this->request->getHost() . "/uploads/images/" . $image->getPath() : '';
    
            return $path;
        }
    }
    
  3. 最后一步是注册此处理程序。我还注入了request服务,以便在我的处理程序中生成映像的完整Web路径。

    app.image_type_handler:
        class: AppBundle\Serializer\ImageTypeHandler
        arguments: ["@request"]
        scope: request
        tags:
            - { name: jms_serializer.subscribing_handler }
    
  4. 此外,您可以使用this解决方法修改post_serialize事件中的序列化数据。