【问题标题】:Symfony 3.3.8 ignoring custom normalizerSymfony 3.3.8 忽略自定义规范器
【发布时间】:2018-02-16 16:30:43
【问题描述】:

为什么 symfony 忽略我的自定义规范器?

src/AppBundle/Serializer/Normalizer/ExceptionNormalizer.php

<?php

namespace AppBundle\Serializer\Normalizer;

use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

/**
 * Class ExceptionNormalizer
 */
class ExceptionNormalizer implements NormalizerInterface
{
    /**
     * {@inheritdoc}
     */
    public function normalize($object, $format = null, array $context = array()): array
    {
        return [];
    }

    /**
     * {@inheritdoc}
     */
    public function supportsNormalization($data, $format = null): bool
    {
        return $data instanceof \Exception;
    }
}

src/AppBundle/Resources/config/services.yml

services:
    ...
    app.normalizer.exception:
        class: AppBundle\Serializer\Normalizer\ExceptionNormalizer
        tags:
            - { name: serializer.normalizer }

app/config/config.yml

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }
    #- { resource: services.yml } exclude default services file
    - { resource: "@AppBundle/Resources/config/services.yml" }

异常输出

{"error":{"code":404,"message":"Not Found","exception":[{"message":"AppBundle\Entity\User 对象未找到。","class": “Symfony\组件.....

预期的异常输出

{}

【问题讨论】:

  • 欢迎堆栈溢出。请花一些时间阅读发布指南,否则您可能会得到反对票。
  • 看起来它与规范器无关 - 它没有尝试使用 User 实体
  • @JasonRoman 它的异常规范化器,而不是用户的规范化器。我尝试在其他东西上重新定义异常输出,但我有相同的字符串和异常信息
  • 显示您定义和调用 Serializer 或此 Normalizer 的代码。

标签: php symfony symfony-3.3


【解决方案1】:

您不应该规范化异常。相反,为这种异常创建侦听器,对其进行处理(例如,写入日志)并将所需的输出作为响应返回。

class ExceptionListener
{
/** @var LoggerInterface */
private $logger;


public function __construct(LoggerInterface $logger)
{
    $this->logger = $logger;
}

public function onKernelException(GetResponseForExceptionEvent $event)
{
    $e = $event->getException();
    if ($e instanceof ValidationException) {
        $event->setResponse(new JsonResponse(['error' => $e->getViolations()], 422)
    } elseif ($e instanceof DomainException) {
        $this->logger->warning('Exception ' . get_class($e) , ['message' => $e->getMessage()]);
        $event->setResponse(
        new JsonResponse(['error' => 'Something is wrong with your request.'], 400);
    } elseif ($e instanceof NotFoundHttpException) {
        $event->setResponse(new JsonResponse(['error' => 'Not found.'], 404);
    } else {
        $event->setResponse(new JsonResponse(['error' => $this->translator->trans('http.internal_server_error')], 500);
    }
}

}

更新 services.yml

  app.exception_listener:
    class: Application\Listeners\ExceptionListener
    arguments: ['@domain.logger']
    tags:
      - { name: kernel.event_listener, event: kernel.exception }

进一步阅读有关侦听器和事件https://symfony.com/doc/current/event_dispatcher.html

您的规范化程序很可能被忽略,因为您没有在序列化程序中注册它。

【讨论】: