JMS序列化器使用抽象父类反序列化 [英] JMS Serializer Deserialize with abstract parent class

查看:168
本文介绍了JMS序列化器使用抽象父类反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象的父级(映射的超级)类,其中有几个具有不同属性的孩子,我想对它们进行反序列化。
我使用MongoDB和Doctrine ODM存储数据,所以我还有一个discriminator字段,该字段告诉doctrine使用了哪个子类(并且在顶部还有一个自定义的 type属性,该属性在其他地方用于确定哪个类是

I have an abstract parent (mapped super-)class which has several children with different properties which I'd like to deserialize. I'm storing the data using MongoDB and Doctrine ODM, so I also have a discriminator field which tells doctrine which subclass is used (and also have a custom "type" property ontop which is used elsewhere to determine which class is currently processed).

反序列化我的模型时,出现一个异常告诉我,不可能创建一个抽象类的实例(当然)-现在我在想如何告诉JMS Deserializer应该使用哪个继承的类(这就是为什么我使用自定义 type 实例变量的原因-因为我无权访问主义的鉴别字段映射)。

When deserializing my model, I get an exception telling me that its impossible to create an instance of an abstract class (ofcourse) - now I'm wondering how I can tell the JMS Deserializer which inherited class it should use (that is why I use a custom type instance variable for example - because I have no access to doctrine's discriminator field mapping).

我可以成功连接到 preDeserializeEvent -,所以也许可以在其中进行一些切换/操作(或使用)?

I can successfully hook into the preDeserializeEvent- so maybe it is possible to make some switch/cases there (or using the )?

我的模型简称(抽象类):

My Model in short (abstract class):

<?php 

namespace VBCMS\Bundle\AdminBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use JMS\Serializer\Annotation as Serializer;

/**
 * abstract Class Module
 * @Serializer\AccessType("public_method")
 * @MongoDB\MappedSuperclass
 * @MongoDB\InheritanceType("SINGLE_COLLECTION")
 * @MongoDB\DiscriminatorField(fieldName="_discriminator_field")
 * @MongoDB\DiscriminatorMap({
 *    "module"="Module",
 *    "text_module"="TextModule",
 *    "menu_module"="MenuModule",
 *    "image_module"="ImageModule"
 * })
 */
abstract class Module {

  const TYPE_MODULE_TEXT        = 'module.text';
  const TYPE_MODULE_MENU        = 'module.menu';
  const TYPE_MODULE_MEDIA_ITEM  = 'module.media.item';

  /**
   * @Serializer\Type("string")
   * @MongoDB\Field(type="string")
   * @var String
   */
  protected $type;

  /**
   * @Serializer\Type("boolean")
   * @MongoDB\Field(type="boolean")
   * @var boolean
   */
  protected $visible;

  // getter/setter methods etc..
}

?>

其中一个子类

<?php
namespace VBCMS\Bundle\AdminBundle\Document;

use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
use JMS\Serializer\Annotation as Serializer;

/**
 * Class TextModule
 * @package VBCMS\Bundle\AdminBundle\Document
 * @Serializer\AccessType("public_method")
 * @MongoDB\EmbeddedDocument
 */
class TextModule extends Module {

    const TEXT_TYPE_SPLASH_HEADLINE = 'splashscreen.headline';
    const TEXT_TYPE_SPLASH_SUBLINE  = 'splashscreen.subline';

    /**
     * the actual text
     *
     * @var string
     * @Serializer\Type("string")
     * @MongoDB\Field(type="string")
     */
    protected $text;

    /**
     * how it is called in the admin interface
     *
     * @var string
     * @Serializer\Type("string")
     * @MongoDB\Field(type="string")
     */
    protected $label;

    /**
     * @var string
     * @Serializer\Type("string")
     * @MongoDB\Field(type="string")
     */
    protected $textType;

    // getter/setter methods etc..
?>

另一项测试是不制作 Module类抽象并创建一个自定义静态方法

Another test was to not make the Module class abstract and to create a custom static method

/**
 *
 * @Serializer\HandlerCallback("json", direction="deserialization")
 * @param JsonDeserializationVisitor $visitor
 */
public static function deserializeToObject(JsonDeserializationVisitor $visitor)
{
  // modify visitor somehow to return an instance of the desired inherited module class??
}

有什么想法吗?

推荐答案

我在插件的Tests目录中找到了一个区分符映射,不幸的是,这尚未记录: https://github.com/schmittjoh/serializer/blob/master/tests/JMS/Serializer/Tests/Fixtures/Discriminator/Vehicle .php

I found a discriminator mapping in the Tests directory of the plugin, unfortunately, this is not yet documented: https://github.com/schmittjoh/serializer/blob/master/tests/JMS/Serializer/Tests/Fixtures/Discriminator/Vehicle.php

文档已更新 http://jmsyst.com/libs/serializer/master/reference/annotations#discriminator

namespace JMS\Serializer\Tests\Fixtures\Discriminator;

use JMS\Serializer\Annotation as Serializer;

/**
 * @Serializer\Discriminator(field = "type", map = {
 *    "car": "JMS\Serializer\Tests\Fixtures\Discriminator\Car",
 *    "moped": "JMS\Serializer\Tests\Fixtures\Discriminator\Moped",
 * })
 */
abstract class Vehicle
{
    /** @Serializer\Type("integer") */
    public $km;

    public function __construct($km)
    {
        $this->km = (integer) $km;
    }
}

这篇关于JMS序列化器使用抽象父类反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆