如何使JMS序列化程序在反序列化JSON而不是强制类型时引发异常? [英] How to make JMS Serializer throw an exception on deserializing JSON instead of coercing types?

查看:119
本文介绍了如何使JMS序列化程序在反序列化JSON而不是强制类型时引发异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个REST API,该API在Symfony2中使用来自PUT请求的JSON.将JSON反序列化为实体的工作原理–但是,如果JSON中的属性类型与实体的对应属性不匹配,JMS序列化程序似乎会强制从JSON转换类型,而不是引发异常.

I'm trying to write a REST API which consumes a JSON from a PUT request in Symfony2. Deserializing the JSON to an entity sort of works – but the JMS Serializer seems to coerce types from the JSON instead of throwing an exception if the type of a property in the JSON does not match the entity’s corresponding property.

例如...

{ "id" : "123" }

…将导致…

int(123)

…如果属性id在实体中定义为整数.

… if the property id is defined as an integer in the entity.

但是我希望JMS序列化器抛出异常.有人知道如何实现这一目标吗?

But I would like JMS Serializer to throw an exception instead. Does anyone know how to achieve this?

我发现JMS序列化程序的类型处理存在一个问题:

One problem with JMS Serializer’s type handling I found is this:

{ "id" : "n123" }

将导致…

int(0)

这是完全不希望的.

有人可以指出我正确的方向吗?

Can someone please point me into the right direction?

推荐答案

在Github寻求帮助之后我想分享自己的问题的答案.

After getting help over at Github I want to share an answer on my own question.

解决方案的关键是使用实现JMS\Serializer\Handler\SubscribingHandlerInterface(例如StrictIntegerHandler)的自定义处理程序.

The key to a solution is using a custom handler which implements the JMS\Serializer\Handler\SubscribingHandlerInterface (e.g. 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);
    }
}

然后,您需要将序列化程序定义为服务:

You will then need to define the serializer as a service:

services:
    mybundle.serializer.strictinteger:
        class: MyBundle\Serializer\StrictIntegerHandler
        tags:
            - { name: jms_serializer.subscribing_handler }

然后您将可以使用strict_integer类型:

Then you will be able to use the type strict_integer:

MyBundle\Entity\MyEntity:
    exclusion_policy: ALL
    properties:
        id:
            expose: true
            type: strict_integer

然后在控制器中反序列化照常进行.

Deserializing in the controller then works as usual.

奖金:现在终于可以使用类型验证器了:

Bonus: Using a type validator now finally makes sense:

MyBundle\Entity\MyEntity:
    properties:
        id:
            - Type:
                type: integer
                message: id {{ value }} is not an integer.

我希望这对遇到同样问题的人有所帮助.

I hope this helps those with the same problem.

这篇关于如何使JMS序列化程序在反序列化JSON而不是强制类型时引发异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆