Symfony: Как заставить JMS Serializer работать со строгими типами?

Это моя ситуация:

Я пытаюсь написать API-интерфейс Symfony REST, который работает со «строгими» типами (целочисленными, логическими и с плавающей точкой), потому что поведение Symfony по умолчанию не поддерживает его, и я хочу избежать принудительного приведения типов (например: Сериализатор JMS преобразует строковое значение в тип целочисленного поля)

Для этого я создал собственный обработчик, который реализует 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 Serializer возвращает правильные результаты:

  1. { "age" : 12 } приведет к int(12)
  2. { "age" : "asdf" } приведет к "Age field has wrong type"

В обоих случаях мой метод deserializeStrictIntegerFromJSON называется, поэтому процесс десериализации работает отлично, как я хочу.

Проблемы приходят с процессом сериализации:
Когда я запускаю действие GET (/person/id_person) Я получаю следующее исключение:

Ожидаемый объект, но получил целое число. У вас неправильное отображение @Type
или это может быть Доктриной отношение многих ко многим?
(JMS \ Serializer \ Exception \ LogicException)

Трассировка стека отладки показывает мне этот метод serializeStrictIntegerToJSON никогда не называется ..

Как я могу решить это? Благодарю.

4

Решение

Я нашел решение: мне пришлось обновить jms/serializer библиотека до версии 1.5.0.

Моя проблема была в том, что я использовал jms/serializer (v1.1.0) чей SerializationContext класс бросал предыдущий LogicException в isVisiting() метод, потому что strict_integer тип не распознается в предложении о переключении accept() метод GraphNavigator учебный класс.

1

Другие решения

Это моя ситуация:

Я пытаюсь написать API-интерфейс Symfony REST, который работает со «строгими» типами (целочисленными, логическими и с плавающей точкой), потому что поведение Symfony по умолчанию не поддерживает его, и я хочу избежать принудительного приведения типов (например: Сериализатор JMS преобразует строковое значение в тип целочисленного поля)

Для этого я создал собственный обработчик, который реализует 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 Serializer возвращает правильные результаты:

  1. { "age" : 12 } приведет к int(12)
  2. { "age" : "asdf" } приведет к "Age field has wrong type"

В обоих случаях мой метод deserializeStrictIntegerFromJSON называется, поэтому процесс десериализации работает отлично, как я хочу.

Проблемы приходят с процессом сериализации:
Когда я запускаю действие GET (/person/id_person) Я получаю следующее исключение:

Ожидаемый объект, но получил целое число. У вас неправильное отображение @Type
или это может быть Доктриной отношение многих ко многим?
(JMS \ Serializer \ Exception \ LogicException)

Трассировка стека отладки показывает мне этот метод serializeStrictIntegerToJSON никогда не называется ..

Как я могу решить это? Благодарю.

4

Я нашел решение: мне пришлось обновить jms/serializer библиотека до версии 1.5.0.

Моя проблема была в том, что я использовал jms/serializer (v1.1.0) чей SerializationContext класс бросал предыдущий LogicException в isVisiting() метод, потому что strict_integer тип не распознается в предложении о переключении accept() метод GraphNavigator учебный класс.

active «data-shortcut =» A
самый старый «data-shortcut =» O
голосует «data-shortcut =» V
1
По вопросам рекламы [email protected]