正如标题所说,我正在尝试在运行时决定是否在序列化中包含字段。就我而言,此决定将基于权限。
我正在使用 Symfony 2,所以我要做的是添加一个名为 @ExcludeIf 的附加注释,它接受一个安全表达式。
我可以处理元数据的注释解析和存储,但我看不到如何将自定义排除策略与库集成。
有什么建议么?
注意:排除策略是 JMS 代码库中的实际构造,我只是无法找出在其他之上集成额外的最佳方法
PS:我之前曾问过这个问题,并被指出使用组。由于各种原因,这对于我的需求来说是一个非常糟糕的解决方案。
正如标题所说,我正在尝试在运行时决定是否在序列化中包含字段。就我而言,此决定将基于权限。
我正在使用 Symfony 2,所以我要做的是添加一个名为 @ExcludeIf 的附加注释,它接受一个安全表达式。
我可以处理元数据的注释解析和存储,但我看不到如何将自定义排除策略与库集成。
有什么建议么?
注意:排除策略是 JMS 代码库中的实际构造,我只是无法找出在其他之上集成额外的最佳方法
PS:我之前曾问过这个问题,并被指出使用组。由于各种原因,这对于我的需求来说是一个非常糟糕的解决方案。
您只需要创建一个实现的类JMS\Serializer\Exclusion\ExclusionStrategyInterface
<?php
namespace JMS\Serializer\Exclusion;
use JMS\Serializer\Metadata\ClassMetadata;
use JMS\Serializer\Metadata\PropertyMetadata;
use JMS\Serializer\Context;
interface ExclusionStrategyInterface
{
/**
* Whether the class should be skipped.
*
* @param ClassMetadata $metadata
*
* @return boolean
*/
public function shouldSkipClass(ClassMetadata $metadata, Context $context);
/**
* Whether the property should be skipped.
*
* @param PropertyMetadata $property
*
* @return boolean
*/
public function shouldSkipProperty(PropertyMetadata $property, Context $context);
}
在您的情况下,您可以在方法中实现自己的自定义逻辑shouldSkipProperty并始终返回falsefor shouldSkipClass。
我们将引用创建的服务,acme.my_exclusion_strategy_service如下所示。
在您的控制器操作中:
<?php
use Symfony\Component\HttpFoundation\Response;
use JMS\Serializer\SerializationContext;
// ....
$context = SerializationContext::create()
->addExclusionStrategy($this->get('acme.my_exclusion_strategy_service'));
$serial = $this->get('jms_serializer')->serialize($object, 'json', $context);
return new Response($serial, Response::HTTP_OK, array('Content-Type' => 'application/json'));
或者,如果您使用 FOSRestBundle
<?php
use FOS\RestBundle\View;
use JMS\Serializer\SerializationContext;
// ....
$context = SerializationContext::create()
->addExclusionStrategy($this->get('acme.my_exclusion_strategy_service'))
$view = new View($object);
$view->setSerializationContext($context);
// or you can create your own view factory that handles the creation
// of the context for you
return $this->get('fos_rest.view_handler')->handle($view);
从jms/serializer1.4.0 开始,symfony 表达式语言被集成在其核心中。
该功能记录在http://jmsyst.com/libs/serializer/master/cookbook/exclusion_strategies#dynamic-exclusion-strategy并且允许使用运行时排除策略。
从文档中获取的示例是:
class MyObject
{
/**
* @Exclude(if="service('user_manager_service').getSomeRuntimeData(object)")
*/
private $name;
/**
* @Expose(if="service('request_stack').getCurrent().has('foo')")
*/
private $name2;
}
在此示例中,服务user_manager_service和request_stack在运行时被调用,并且取决于返回(true或false),属性将被公开或不公开。
使用相同的表达式语言,从 1.6.0 开始也可以通过表达式语言使用虚拟属性。记录在http://jmsyst.com/libs/serializer/master/reference/annotations#virtualproperty允许添加来自外部服务的动态数据