我无法覆盖jms序列化程序包中的默认处理程序。
我想改变Symfony\Component\Validator\ConstraintViolationList
序列化的方式,所以我编写了自己的自定义处理程序。并按照文档(以及各种stackoverflow答案)中的描述正确标记它。
但是,我的处理程序一直被JMS Serializer包附带的ConstraintViolationList的默认处理程序覆盖。
我已正确标记了我的处理程序服务。事实上,当我从ms_serializer.constraint_violation_handler
vendor/jms/serializer-bundle/JMS/SerializerBundle/Resources/config/services.xml
服务定义时,我的处理程序服务被检测到并正确使用
如何阻止默认处理程序覆盖我的自定义处理程序?
我甚至尝试从我自己的捆绑中覆盖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>
答案 0 :(得分:1)
这种情况正在发生,因为JMSSerializerBundle是在AppKernel中捆绑后注册的,这意味着我定义的任何服务都将被JMS Serializer的版本覆盖。
解决方案:将您的软件包放在AppKernel.php的最底部,如下所示:
public function registerBundles()
{
$bundles = [
// .......
new JMS\SerializerBundle\JMSSerializerBundle(),
new My\Bundle\MyAwesomeBundle()
];
return $bundles;
}
答案 1 :(得分:0)
对于版本
"name": "jms/serializer-bundle",
"version": "3.5.0",
"name": "symfony/framework-bundle",
"version": "v5.0.5",
决策应该像这样,'priority' => -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默认处理程序