symfony - JMS Serializer 使用抽象父类反序列化

标签 symfony deserialization doctrine-odm jmsserializerbundle

我有一个抽象的父类(映射的超)类,它有几个具有不同属性的子类,我想反序列化它们。
我正在使用 MongoDB 和 Doctrine ODM 存储数据,所以我还有一个鉴别器字段,它告诉教义使用哪个子类(并且还有一个自定义的“类型”属性在其他地方用于确定当前正在处理的类)。

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

我可以成功挂入preDeserializeEvent - 所以也许有可能在那里(或使用 )做一些开关/案例?

简而言之我的模型(抽象类):

<?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 类抽象并创建自定义静态方法
/**
 *
 * @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

文档更新 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;
    }
}

关于symfony - JMS Serializer 使用抽象父类反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17275117/

相关文章:

git - 为什么来自 github 的递归子模块更新对于 DoctrineMongoORMModule 失败?

doctrine-orm - 使用 Doctrine 2 MongoDbODM 模块进行身份验证

symfony - 尝试使用 targetPath 登录 Symfony 后重定向用户,但它始终为 null

java - 如何反序列化Java中隐藏的ServiceProvider类对象?

forms - 如何在我的类型类中访问我的服务(DependencyInjection)?

c# - 反序列化 :anyType 的列表

apache-spark - 无法在 pyspark : "java.lang.NoSuchMethodException" 中加载保存的 Spark 模型

php - 如何在 zf2 中使用户名不区分大小写

symfony2.6doctrine2schema_filter参数不存在

php - 为 @ID 字段插入 null 的 Doctrine