rei*_*ter 5 symfony jmsserializerbundle json-deserialization jms-serializer
我正在尝试编写一个REST API,它在Symfony2中使用来自PUT请求的JSON.将JSON反序列化为实体类型 - 但是如果JSON中的属性类型与实体的相应属性不匹配,则JMS Serializer似乎强制来自JSON的类型而不是抛出异常.
例如 …
{ "id" : "123" }
Run Code Online (Sandbox Code Playgroud)
......会导致......
int(123)
Run Code Online (Sandbox Code Playgroud)
...如果属性id
在实体中定义为整数.
但我希望JMS Serializer能够抛出异常.有谁知道如何实现这一目标?
我发现JMS Serializer的类型处理的一个问题是:
{ "id" : "n123" }
Run Code Online (Sandbox Code Playgroud)
会导致......
int(0)
Run Code Online (Sandbox Code Playgroud)
这是完全不受欢迎的.
有人可以指出我正确的方向吗?
后在Github上得到帮助了,我想分享我自己的问题的答案.
解决方案的关键是使用实现JMS\Serializer\Handler\SubscribingHandlerInterface
(例如a StrictIntegerHandler
)的自定义处理程序.
<?php
namespace MyBundle\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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您需要将序列化程序定义为服务:
services:
mybundle.serializer.strictinteger:
class: MyBundle\Serializer\StrictIntegerHandler
tags:
- { name: jms_serializer.subscribing_handler }
Run Code Online (Sandbox Code Playgroud)
然后你就可以使用这个类型了strict_integer
:
MyBundle\Entity\MyEntity:
exclusion_policy: ALL
properties:
id:
expose: true
type: strict_integer
Run Code Online (Sandbox Code Playgroud)
然后在控制器中反序列化然后照常工作.
奖励:现在使用类型验证器最终有意义:
MyBundle\Entity\MyEntity:
properties:
id:
- Type:
type: integer
message: id {{ value }} is not an integer.
Run Code Online (Sandbox Code Playgroud)
我希望这可以帮助那些有同样问题的人.