JMSSerializerBundle - 保留关系名称
JMSSerializerBundle - preserve relation name
我将 Symfony2 与 JMSSerializerBundle 一起使用。最后一个我是新手 =) 在这种情况下我应该怎么做:
我有图像模型。它包含一些字段,但主要字段是 "name"。另外,我有一些模型,它参考了图像模型。例如用户和应用程序。用户模型有 OneToOne 字段 "avatar",应用程序有 OneToOne 字段 "icon"。现在,我想序列化 User 实例并得到类似
的东西
{
...,
"avatar": "http://example.com/my/image/path/image_name.png",
....
}
另外,我想序列化Application并得到
{
...,
"icon": "http://example.com/my/image/path/another_image_name.png",
...
}
我在 User::avatar 和 Application::icon 字段上使用 @Inline 批注将图像对象(与此字段相关)减少为单个标量值(仅需要图像 "name")。此外,我的图像模型具有 ExclusionPolicy("all"),并且仅公开 "name" 字段。现在,JMSSerializer 输出是
(For User instance)
{
...,
"name": "http://example.com/my/image/path/image_name.png",
...
}
(For Application instance)
{
...,
"name": "http://example.com/my/image/path/another_image_name.png",
...
}
问题是:如何使 JMSSerializer 保留序列化数组中的 "avatar" 和 "icon" 键而不是 "name"?
终于,我找到了解决办法。在我看来,它不是很优雅和漂亮,但是很管用。
我告诉 JMSSerializer,User::avatar 和 Application::icon 是图像。为此,我使用了注释 @Type("Image")
//src\AppBundle\Entity\User.php
//...
/**
* @var integer
*
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Image")
* @ORM\JoinColumn(name="avatar", referencedColumnName="id")
*
* @JMS\Expose()
* @JMS\Type("Image")
*/
private $avatar;
//...
//src\AppBundle\Entity\Application.php
//...
/**
* @var integer
*
* @ORM\OneToOne(targetEntity="AppBundle\Entity\Image")
* @ORM\JoinColumn(name="icon", referencedColumnName="id")
*
* @JMS\Expose()
* @JMS\Type("Image")
*/
private $icon;
//...
我实现了处理程序,它将类型为 Image
的对象序列化为 json
。
<?php
//src\AppBundle\Serializer\ImageTypeHandler.php
namespace AppBundle\Serializer;
use AppBundle\Entity\Image;
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonSerializationVisitor;
use Symfony\Component\HttpFoundation\Request;
class ImageTypeHandler implements SubscribingHandlerInterface
{
private $request;
public function __construct(Request $request) {
$this->request = $request;
}
static public function getSubscribingMethods()
{
return [
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'Image',
'method' => 'serializeImageToWebPath'
]
];
}
public function serializeImageToWebPath(JsonSerializationVisitor $visitor, Image $image = null, array $type, Context $context)
{
$path = $image ? "http://" . $this->request->getHost() . "/uploads/images/" . $image->getPath() : '';
return $path;
}
}
最后一步是注册这个处理程序。我还注入了 request
服务以在我的处理程序中生成图像的完整 Web 路径。
app.image_type_handler:
class: AppBundle\Serializer\ImageTypeHandler
arguments: ["@request"]
scope: request
tags:
- { name: jms_serializer.subscribing_handler }
此外,您可以使用 this 变通方法来修改 post_serialize 事件中的序列化数据。
我将 Symfony2 与 JMSSerializerBundle 一起使用。最后一个我是新手 =) 在这种情况下我应该怎么做:
我有图像模型。它包含一些字段,但主要字段是 "name"。另外,我有一些模型,它参考了图像模型。例如用户和应用程序。用户模型有 OneToOne 字段 "avatar",应用程序有 OneToOne 字段 "icon"。现在,我想序列化 User 实例并得到类似
的东西{
...,
"avatar": "http://example.com/my/image/path/image_name.png",
....
}
另外,我想序列化Application并得到
{
...,
"icon": "http://example.com/my/image/path/another_image_name.png",
...
}
我在 User::avatar 和 Application::icon 字段上使用 @Inline 批注将图像对象(与此字段相关)减少为单个标量值(仅需要图像 "name")。此外,我的图像模型具有 ExclusionPolicy("all"),并且仅公开 "name" 字段。现在,JMSSerializer 输出是
(For User instance)
{
...,
"name": "http://example.com/my/image/path/image_name.png",
...
}
(For Application instance)
{
...,
"name": "http://example.com/my/image/path/another_image_name.png",
...
}
问题是:如何使 JMSSerializer 保留序列化数组中的 "avatar" 和 "icon" 键而不是 "name"?
终于,我找到了解决办法。在我看来,它不是很优雅和漂亮,但是很管用。
我告诉 JMSSerializer,User::avatar 和 Application::icon 是图像。为此,我使用了注释
@Type("Image")
//src\AppBundle\Entity\User.php //... /** * @var integer * * @ORM\OneToOne(targetEntity="AppBundle\Entity\Image") * @ORM\JoinColumn(name="avatar", referencedColumnName="id") * * @JMS\Expose() * @JMS\Type("Image") */ private $avatar; //... //src\AppBundle\Entity\Application.php //... /** * @var integer * * @ORM\OneToOne(targetEntity="AppBundle\Entity\Image") * @ORM\JoinColumn(name="icon", referencedColumnName="id") * * @JMS\Expose() * @JMS\Type("Image") */ private $icon; //...
我实现了处理程序,它将类型为
Image
的对象序列化为json
。<?php //src\AppBundle\Serializer\ImageTypeHandler.php namespace AppBundle\Serializer; use AppBundle\Entity\Image; use JMS\Serializer\Context; use JMS\Serializer\GraphNavigator; use JMS\Serializer\Handler\SubscribingHandlerInterface; use JMS\Serializer\JsonSerializationVisitor; use Symfony\Component\HttpFoundation\Request; class ImageTypeHandler implements SubscribingHandlerInterface { private $request; public function __construct(Request $request) { $this->request = $request; } static public function getSubscribingMethods() { return [ [ 'direction' => GraphNavigator::DIRECTION_SERIALIZATION, 'format' => 'json', 'type' => 'Image', 'method' => 'serializeImageToWebPath' ] ]; } public function serializeImageToWebPath(JsonSerializationVisitor $visitor, Image $image = null, array $type, Context $context) { $path = $image ? "http://" . $this->request->getHost() . "/uploads/images/" . $image->getPath() : ''; return $path; } }
最后一步是注册这个处理程序。我还注入了
request
服务以在我的处理程序中生成图像的完整 Web 路径。app.image_type_handler: class: AppBundle\Serializer\ImageTypeHandler arguments: ["@request"] scope: request tags: - { name: jms_serializer.subscribing_handler }
此外,您可以使用 this 变通方法来修改 post_serialize 事件中的序列化数据。