【问题标题】:Unable to override JMS Serializer's default handler for Symfony ConstraintViolationList无法为 Symfony ConstraintViolationList 覆盖 JMS 序列化程序的默认处理程序
【发布时间】:2016-10-24 23:21:09
【问题描述】:

我无法覆盖 jms 序列化程序包中的默认处理程序。

我想改变Symfony\Component\Validator\ConstraintViolationList 的序列化方式,所以我编写了自己的自定义处理程序。并按照文档中的描述正确标记它(以及各种stackoverflow答案)。

但是,我的处理程序一直被 JMS Serializer 捆绑包附带的 ConstraintViolationList 的默认处理程序覆盖。

我已正确标记我的处理程序服务。事实上,当我从vendor/jms/serializer-bundle/JMS/SerializerBundle/Resources/config/services.xml 注释掉ms_serializer.constraint_violation_handler 服务定义时,我的处理程序服务被检测到并正确使用

如何阻止默认处理程序覆盖我的自定义处理程序?

我什至尝试从我自己的包中覆盖jms_serializer.constraint_violation_handler.class 参数,但仍然没有运气。

这是我的 Handler 类:

<?php
namespace Coanda\Bridge\JMSSerializer\Handler;

use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonSerializationVisitor;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;

class ConstraintViolationHandler implements SubscribingHandlerInterface
{
    public static function getSubscribingMethods()
    {
        $methods = [];
        $methods[] = [
            'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
            'type' => ConstraintViolationList::class,
            'format' => 'json',
            'method' => 'serializeListToJson'
        ];
        return $methods;
    }

    public function serializeListToJson(
        JsonSerializationVisitor $visitor,
        ConstraintViolationList $list,
        array $type,
        Context $context
    ) {
        $violations = [];
        foreach ($list as $item) {
            $violations[$item->getPropertyPath()][] = $item->getMessage();
        }
        if (null === $visitor->getRoot()) {
            $visitor->setRoot($violations);
        }
        return $violations;
    }

}

我已经在我的services.xml注册了它

    <service id="coanda.serializer.constraint_violation_handler"
        class="Coanda\Bridge\JMSSerializer\Handler\ConstraintViolationHandler">
        <tag name="jms_serializer.subscribing_handler"
            type="Symfony\Component\Validator\ConstraintViolationList"
            direction="serialization" format="json" method="serializeListToJson" />
    </service>

【问题讨论】:

  • 我在 symfony 5 中遇到了同样的情况,但不知道如何解决它

标签: php symfony serialization jmsserializerbundle jms-serializer


【解决方案1】:

发生这种情况是因为 JMSSerializerBundle 是在我的包之后在 AppKernel 中注册的,这意味着我定义的任何服务都将被 JMS Serializer 的版本覆盖。

解决方案:将你的包放在 AppKernel.php 的最底部,如下所示:

public function registerBundles()
{
    $bundles = [
        // .......
        new JMS\SerializerBundle\JMSSerializerBundle(),
        new My\Bundle\MyAwesomeBundle()
    ];

    return $bundles;
}

【讨论】:

    【解决方案2】:

    对于版本

    "name": "jms/serializer-bundle",
    "version": "3.5.0",
    
    "name": "symfony/framework-bundle",
    "version": "v5.0.5",
    

    决定应该是这样的,'priority' =&gt; -915应该在getSubscribingMethods

        /**
         * @return array
         */
        public static function getSubscribingMethods()
        {
            return [
                [
                    'direction' => GraphNavigatorInterface::DIRECTION_SERIALIZATION,
                    'format' => 'json',
                    'type' => ConstraintViolationList::class,
                    'method' => 'serializeCustomListToJson',
                    'priority' => -915
                ]
            ];
        }
    

    然后\JMS\SerializerBundle\DependencyInjection\Compiler\CustomHandlersPass::sortAndFlattenHandlersList 将其移动到最后一个位置并在处理程序中设置自定义服务而不是 jms 默认处理程序

    【讨论】:

      【解决方案3】:

      这个配置对我有用:

          exception:
              enabled: true
              serializer_error_renderer: true
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-26
        • 2016-04-13
        • 1970-01-01
        • 2015-10-07
        • 1970-01-01
        • 2020-11-27
        • 2016-06-04
        相关资源
        最近更新 更多