【问题标题】:Symfony: How to make JMS Serializer works with strict types?Symfony:如何使 JMS 序列化器与严格类型一起工作?
【发布时间】:2017-10-07 16:25:28
【问题描述】:

这是我的情况:

我正在尝试编写一个适用于“严格”类型(整数、布尔值和浮点数)的 Symfony REST API,因为默认的 Symfony 行为不支持它并且我想避免强制转换类型(例如:@987654321 @)

为此,我创建了一个自定义处理程序,它实现了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 序列化程序会返回正确的结果:

  1. { "age" : 12 } 将导致 int(12)
  2. { "age" : "asdf" } 将导致 "Age field has wrong type"

在这两种情况下,我的方法 deserializeStrictIntegerFromJSON 都会被调用,因此反序列化过程可以按我的意愿完美运行。

序列化过程带来的问题: 当我启动 GET 操作 (/person/id_person) 时,出现以下异常:

预期的对象,但得到整数。你有错误的@Type 映射吗 或者这可能是一个多对多的关系吗? (JMS\Serializer\Exception\LogicException)

调试堆栈跟踪显示方法 serializeStrictIntegerToJSON 从未被调用..

我该如何解决?谢谢。

【问题讨论】:

    标签: php symfony serialization jmsserializerbundle visitor-pattern


    【解决方案1】:

    我找到了解决方案:我必须将jms/serializer 库升级到版本 1.5.0。

    我的问题是我使用了jms/serializer (v1.1.0),其SerializationContext 类在isVisiting() 方法中抛出了前一个LogicException,因为strict_integer 类型在来自@ 的switch-case 语句中无法识别GraphNavigator类的987654327@方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      相关资源
      最近更新 更多