【问题标题】:Symfony5 - Overriding Error output for non-HTML formatsSymfony5 - 覆盖非 HTML 格式的错误输出
【发布时间】:2021-08-12 00:50:34
【问题描述】:

我尝试通过官方文档处理所有异常(Symfony 5):https://symfony.com/doc/current/controller/error_pages.html#overriding-error-output-for-non-html-formats

我想将所有异常序列化为 JSON 格式。 我在本主题中阅读了类似问题的解决方案:How to format all HttpExceptions as json in symfony5? 但不能解决我的问题。

我的文件:src/Controller/ShowController.php

<?php

namespace App\Controller;

use App\Component\ShowResponseHandlerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;

class ShowController extends AbstractController
{
    /**
     * @Route("/show/{file}", name="show", requirements={"file"=".+"})
     */
    public function index(string $file, string $storageDirectory): Response
    {
        $absolutePath = $storageDirectory.$file;
        if(!file_exists($absolutePath)) {
            throw new NotFoundHttpException("Resource not exists");
        }

        return new BinaryFileResponse($absolutePath);

    }
}

src/Serializer/ProblemNormalizer.php

<?php
namespace App\Serializer;

use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class ProblemNormalizer implements NormalizerInterface
{

    public function normalize($exception, string $format = null, array $context = [])
    {
        return [
            'success' => false,
            'exception'=> [
                'message' => $exception->getMessage(),
                'code' => $exception->getStatusCode(),
            ]
        ];
    }

    public function supportsNormalization($data, string $format = null)
    {
        return $data instanceof FlattenException;
    }
}

config/services.yaml

services:
_defaults:
    autowire: true      # Automatically injects dependencies in your services.
    autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.

    App\Serializer\ProblemNormalizer:
        tags: ['serializer.normalizer']

当然我已经安装了包 symfony/serializer

composer show -i | grep "symfony/serializer"

symfony/serializer                 v5.2.9  Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON

我做错了什么或没有配置什么? 它总是返回 html 输出。

更新

控制台输出:

symfony console debug:container | grep normalizer
  Symfony\Component\Serializer\Normalizer\DenormalizerInterface                alias for "serializer"                                                                     
  Symfony\Component\Serializer\Normalizer\ObjectNormalizer                     alias for "serializer.normalizer.object"                                                   
  Symfony\Component\Serializer\Normalizer\PropertyNormalizer                   alias for "serializer.normalizer.property"                                                 
  maker.auto_command.make_serializer_normalizer                                Symfony\Bundle\MakerBundle\Command\MakerCommand                                            
  maker.maker.make_serializer_normalizer                                       Symfony\Bundle\MakerBundle\Maker\MakeSerializerNormalizer                                  
  serializer.denormalizer.array                                                Symfony\Component\Serializer\Normalizer\ArrayDenormalizer                                  
  serializer.denormalizer.unwrapping                                           Symfony\Component\Serializer\Normalizer\UnwrappingDenormalizer                             
  serializer.normalizer.constraint_violation_list                              Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer                  
  serializer.normalizer.data_uri                                               Symfony\Component\Serializer\Normalizer\DataUriNormalizer                                  
  serializer.normalizer.dateinterval                                           Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer                             
  serializer.normalizer.datetime                                               Symfony\Component\Serializer\Normalizer\DateTimeNormalizer                                 
  serializer.normalizer.datetimezone                                           Symfony\Component\Serializer\Normalizer\DateTimeZoneNormalizer                             
  serializer.normalizer.flatten_exception                                      Symfony\Component\Messenger\Transport\Serialization\Normalizer\FlattenExceptionNormalizer  
  serializer.normalizer.form_error                                             Symfony\Component\Serializer\Normalizer\FormErrorNormalizer                                
  serializer.normalizer.json_serializable                                      Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer                         
  serializer.normalizer.mime_message                                           Symfony\Component\Serializer\Normalizer\MimeMessageNormalizer                              
  serializer.normalizer.object                                                 Symfony\Component\Serializer\Normalizer\ObjectNormalizer                                   
  serializer.normalizer.problem                                                Symfony\Component\Serializer\Normalizer\ProblemNormalizer                                  
  serializer.normalizer.property                                               Symfony\Component\Serializer\Normalizer\PropertyNormalizer                                 
  serializer.normalizer.uid                                                    Symfony\Component\Serializer\Normalizer\UidNormalizer                                      

 // To search for a specific service, re-run this command with a search term. (e.g. debug:container log) 

【问题讨论】:

  • 您能否检查一下您的规范化器是否已配置为运行symfony console debug:container | grep normalizer
  • @qdequippe 是的。我在我的问题中添加了控制台的输出。

标签: php symfony error-handling symfony5


【解决方案1】:

尝试从 config/services.yaml 中删除 App\Serializer\ProblemNormalizer。再次检查容器的规范化器symfony console debug:container | grep normalizer。通常你应该在没有任何配置的列表中看到你的规范化器(Symfony 通过 NormalizerInterface 识别它)。测试 curl http://localhost:8000/show/foo.doc -H "Accept: application/json"

【讨论】:

  • 谢谢!。原因是。 1.不需要的服务:App\Serializer\ProblemNormalizer 2.其次是。我没有发送带有接受响应为 json 的标头:Accept: application/json.现在我有 json 格式的很好的响应 {"success":false,"exception":{"message":"Resource not exists","code":404}}
  • 考虑使用$context:例如限制响应消息if($context['debug']) {$message = $exception-&gt;getMessage()} else{ $message = $exception-&gt;getStatusText()},您还可以从原始异常中添加额外数据或根据$context['exception']相应地翻译您的消息。
猜你喜欢
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多