JMS序列化捆绑@exclude注释不起作用

时间:2016-02-28 15:56:40

标签: symfony

我的实体FosUserBundle

namespace AppBundle\Entity;

use JMS\Serializer\Annotation\Expose;
use JMS\Serializer\Annotation\Exclude;
use JMS\Serializer\Annotation\ExclusionPolicy;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use FOS\UserBundle\Model\Group;

/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 * @ExclusionPolicy("all")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     * @Exclude
     */
    protected $id;

    /**
     * @ORM\Column(type="integer")
     */
    private $balance = 0;

但是如果我尝试序列化App \ Entity \ User对象:

$this->get('jms_serializer')->serialize($user, 'json');

它返回了我ID字段!

 {
  "id": 1,
  "username": "admin",
  "username_canonical": "admin",
  "email": "admin",
  "email_canonical": "admin",
  "enabled": true,
  "salt": "o12yxgxp3vkk0w4sck80408w8s8o84s",
  "password": "$2y$13$o12yxgxp3vkk0w4sck804uSVjSMSB1W0qwEjunGTHomBqqoGvkW9G",
  "last_login": "2016-02-28T17:28:19+0300",
  "locked": false,
  "expired": false,
  "roles": [
    "ROLE_ADMIN"
  ],
  "credentials_expired": false
}

2 个答案:

答案 0 :(得分:7)

由于FOSU​​serBundle序列化程序规则,您的排除策略将无效。

要使用排除项,您需要告诉JMSSerializer压缩FOSUB序列化。

config.yml中,添加以下内容:

jms_serializer:
    metadata:
        auto_detection: true # Don't forget this line
        directories:
            FOSUB:
                namespace_prefix: FOS\UserBundle
                path: %kernel.root_dir%/serializer/FOSUB

然后,创建文件app/serializer/FOSUB/Model.User.yml并将以下内容粘贴到:

FOS\UserBundle\Model\User:
    exclusion_policy: ALL

现在,排除了所有继承的属性,您可以公开您想要的内容。

如果您想要保留一些属性,或者在您的实体中重新定义它们,请根据您的需要进行调整。

查看相应的问题#78

<强>更新

对于不能正常工作的@Expose注释,请在我之前的示例中添加auto_detection

如果这不能解决问题,请使用@Groups注释并执行以下操作:

use JMS\Serializer\Annotation\Groups;

/**
 * @ORM\Column(type="integer")
 * @JMS\Groups({"user"})
 */
private $balance = 0;

按照以下方式更改您的控制器:

use JMS\Serializer\SerializationContext;

$context = SerializationContext::create()->setGroups(array('user'));
$serializer->serialize($user, 'json', $context);

它应该有效。

请记住,此问题的存在只是因为您的用户实体扩展了已经具有序列化程序规则的类。

答案 1 :(得分:0)

        $serializer = SerializerBuilder::create()
            ->setSerializationContextFactory(function () {
                return \JMS\Serializer\SerializationContext::create()
                    ->setSerializeNull(true)
                    ;
            })
            ->setDeserializationContextFactory(function () {
                return \JMS\Serializer\DeserializationContext::create()
                    ->setSerializeNull(true)
                    ;
            })
            ->setAnnotationReader($annotationReader)
            ->setPropertyNamingStrategy(new SerializedNameImportantThanPropertyNameStrategy())
            ->build();

忽略一些父类:CComponent,CModel,CActiveRecord

        $class = new \ReflectionClass($serializer);
        $property = $class->getProperty('navigator');
        $property->setAccessible(true);
        $navigator = $property->getValue($serializer);

        $class = new \ReflectionClass($navigator);
        $property = $class->getProperty('metadataFactory');
        $property->setAccessible(true);
        $metadataFactory = $property->getValue($navigator);

        $class = new \ReflectionClass($metadataFactory);
        $property = $class->getProperty('loadedClassMetadata');
        $property->setAccessible(true);
        $property->setValue($metadataFactory, [
            'CComponent' => new NullMetadata(new \stdClass()),
            'CModel' => new NullMetadata(new \stdClass()),
            'CActiveRecord' => new NullMetadata(new \stdClass()),
        ]);