JMS Serializer: How to limit the depth of serialisation for an object graph

风流意气都作罢 提交于 2019-12-19 04:12:13

问题


Maybe it is just my misunderstanding of this annotation however it does not seam to work as expected.

I have the following object graph

User
 -> Company
  -> Users
   -> Groups
    -> Permissions

As you can see there will be some recursion. JMS handles this quite well by not serialising the other user's company properties as well as not the current user.

However I want the serialization to stop at and include company.

I have tried this expecting that once the level $context->level = 2 it would stop

<?php
namespace FinalConcept\TimeTracker\EntitiesBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;

/**
 * FinalConcept\TimeTracker\EntitiesBundle\Entity
 *
 * @ORM\Table(name="users")
 * @ORM\Entity(repositoryClass="FinalConcept\TimeTracker\EntitiesBundle\Repository\UserRepository")
 */
class User implements UserInterface, \Serializable
{
     /**
     * @ORM\ManyToOne(targetEntity="company", inversedBy="users")
     * @ORM\JoinColumn(name="company_id", referencedColumnName="id")
     * @JMS\MaxDepth(depth=1)
     */
    private $company;
}

However this is not the case. Even stepping through the code has not shed any light on how to stop this.

I am happy to create a custom handler if I can only invoke it for a specific path i.e. User.Company

I also need this for User.Groups which has the following graph

User
 -> Groups
  -> Permissions
 -> Users
   -> Groups
     -> users ....

Thanks in advance for any help how to limit the depth of serialization for an object graph


回答1:


Because I did not have access to the latest version of the serializer I had to find a workaround to the @MaxDepth. This may also help you.

Use @JMS\ExclusionPolicy("all") on all entities that are connected.

Now use @JMS\Expose only on those properties that you want to have serialize. On join relations only use this annotation in one direction. That will fix your problem.

namespace FinalConcept\TimeTracker\EntitiesBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as JMS;

/**
 * FinalConcept\TimeTracker\EntitiesBundle\Entity
 *
 * @JMS\ExclusionPolicy("all")
 * @ORM\Table(name="users")
 * @ORM\Entity(repositoryClass="FinalConcept\TimeTracker\EntitiesBundle\Repository\UserRepository")
 */
class User implements UserInterface, \Serializable
{
     /**
     * @JMS\Expose
     * @ORM\ManyToOne(targetEntity="company", inversedBy="users")
     * @ORM\JoinColumn(name="company_id", referencedColumnName="id")
     */
    private $company;
}



回答2:


As of the latest version, using @MaxDepth() annotation and SerializationContext::create()->enableMaxDepthChecks() in the controller does the job.



来源:https://stackoverflow.com/questions/22590073/jms-serializer-how-to-limit-the-depth-of-serialisation-for-an-object-graph

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!