我的实体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
}
答案 0 :(得分:7)
由于FOSUserBundle序列化程序规则,您的排除策略将无效。
要使用排除项,您需要告诉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()),
]);