Symfony:如何使 JMS 序列化程序与严格类型一起工作?
Symfony: How to make JMS Serializer works with strict types?
这是我的情况:
我正在尝试编写一个适用于 "strict" 类型(整数、布尔值和浮点数)的 Symfony REST API,因为默认的 Symfony 行为不支持它,我想避免强制转换类型(例如:)
为此,我创建了一个自定义处理程序来实现 JMS\Serializer\Handler\SubscribingHandlerInterface
(例如 StrictIntegerHandler
):
<?php
namespace AppBundle\Serializer;
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonDeserializationVisitor;
use JMS\Serializer\JsonSerializationVisitor;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class StrictIntegerHandler implements SubscribingHandlerInterface
{
public static function getSubscribingMethods()
{
return [
[
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => 'strict_integer',
'method' => 'deserializeStrictIntegerFromJSON',
],
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'strict_integer',
'method' => 'serializeStrictIntegerToJSON',
],
];
}
public function deserializeStrictIntegerFromJSON(
JsonDeserializationVisitor $visitor, $data, array $type)
{
return $data;
}
public function serializeStrictIntegerToJSON(
JsonSerializationVisitor $visitor, $data, array $type, Context $context)
{
return $visitor->visitInteger($data, $type, $context);
}
}
我的实体看起来:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Validator;
/**
* Person
*
* @ORM\Table(name="persons")
* @ORM\Entity(repositoryClass="AppBundle\Repository\PersonRepository")
*/
class Person
{
/**
* @var int age
*
* @ORM\Column(name="age", type="integer")
*
* @Serializer\Type("strict_integer")
* @Serializer\Groups({"Person"})
*
* @Validator\Type(type="integer", message="Age field has wrong type")
*/
private $age;
public function getAge()
{
return $this->age;
}
public function setAge(int $age)
{
$this->age = $age;
}
}
当我抛出以下 POST 操作时,JMS 序列化器 returns 正确的结果:
{ "age" : 12 }
将导致 int(12)
{ "age" : "asdf" }
将导致 "Age field has wrong type"
在这两种情况下,我的方法 deserializeStrictIntegerFromJSON
都被调用了,所以反序列化过程完全符合我的要求。
序列化过程出现问题:
当我启动 GET 操作 (/person/id_person
) 时,出现以下异常:
Expected object but got integer. Do you have the wrong @Type mapping
or could this be a Doctrine many-to-many relation?
(JMS\Serializer\Exception\LogicException)
调试堆栈跟踪显示从未调用方法 serializeStrictIntegerToJSON
..
我该如何解决?谢谢。
我找到了解决方案:我必须将 jms/serializer
库升级到版本 1.5.0。
我的问题是我使用的 jms/serializer
(v1.1.0) 其 SerializationContext
class 将之前的 LogicException
抛出到 isVisiting()
方法中,因为strict_integer
GraphNavigator
class.
的 accept()
方法中的 switch-case 语句无法识别 strict_integer
类型
这是我的情况:
我正在尝试编写一个适用于 "strict" 类型(整数、布尔值和浮点数)的 Symfony REST API,因为默认的 Symfony 行为不支持它,我想避免强制转换类型(例如:
为此,我创建了一个自定义处理程序来实现 JMS\Serializer\Handler\SubscribingHandlerInterface
(例如 StrictIntegerHandler
):
<?php
namespace AppBundle\Serializer;
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonDeserializationVisitor;
use JMS\Serializer\JsonSerializationVisitor;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class StrictIntegerHandler implements SubscribingHandlerInterface
{
public static function getSubscribingMethods()
{
return [
[
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => 'strict_integer',
'method' => 'deserializeStrictIntegerFromJSON',
],
[
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'strict_integer',
'method' => 'serializeStrictIntegerToJSON',
],
];
}
public function deserializeStrictIntegerFromJSON(
JsonDeserializationVisitor $visitor, $data, array $type)
{
return $data;
}
public function serializeStrictIntegerToJSON(
JsonSerializationVisitor $visitor, $data, array $type, Context $context)
{
return $visitor->visitInteger($data, $type, $context);
}
}
我的实体看起来:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation as Serializer;
use Symfony\Component\Validator\Constraints as Validator;
/**
* Person
*
* @ORM\Table(name="persons")
* @ORM\Entity(repositoryClass="AppBundle\Repository\PersonRepository")
*/
class Person
{
/**
* @var int age
*
* @ORM\Column(name="age", type="integer")
*
* @Serializer\Type("strict_integer")
* @Serializer\Groups({"Person"})
*
* @Validator\Type(type="integer", message="Age field has wrong type")
*/
private $age;
public function getAge()
{
return $this->age;
}
public function setAge(int $age)
{
$this->age = $age;
}
}
当我抛出以下 POST 操作时,JMS 序列化器 returns 正确的结果:
{ "age" : 12 }
将导致int(12)
{ "age" : "asdf" }
将导致"Age field has wrong type"
在这两种情况下,我的方法 deserializeStrictIntegerFromJSON
都被调用了,所以反序列化过程完全符合我的要求。
序列化过程出现问题:
当我启动 GET 操作 (/person/id_person
) 时,出现以下异常:
Expected object but got integer. Do you have the wrong @Type mapping or could this be a Doctrine many-to-many relation? (JMS\Serializer\Exception\LogicException)
调试堆栈跟踪显示从未调用方法 serializeStrictIntegerToJSON
..
我该如何解决?谢谢。
我找到了解决方案:我必须将 jms/serializer
库升级到版本 1.5.0。
我的问题是我使用的 jms/serializer
(v1.1.0) 其 SerializationContext
class 将之前的 LogicException
抛出到 isVisiting()
方法中,因为strict_integer
GraphNavigator
class.
accept()
方法中的 switch-case 语句无法识别 strict_integer
类型