Symfony4集成JMS序列化器与FOSRestBundle时序列化报错求助
兄弟,我太懂你这报错的糟心了!我之前用Symfony4搭API的时候也踩过一模一样的坑——本质就是FOSRestBundle在序列化异常对象时,不小心把带资源句柄的服务(比如Monolog的Logger、Cache适配器这类)带进了序列化流程,而JMS序列化器根本没法处理这些资源类型的对象。
给你几个亲测有效的解决办法:
方案1:让FOSRest只序列化异常核心信息,跳过冗余内容
打开config/packages/fos_rest.yaml,修改异常相关配置,让它只返回最必要的异常字段,别去碰那些带资源的上下文或调用栈:fos_rest: exception: enabled: true serialize_exceptions: true exception_normalizer: class: 'FOS\RestBundle\Serializer\Normalizer\ExceptionNormalizer' options: ignore_context: true ignore_trace: true配置完后,返回的异常只会包含
message、status_code这类核心内容,彻底避开那些不能序列化的服务对象。方案2:给JMS序列化器加排除规则
如果你确实需要保留部分上下文信息,那可以直接告诉JMS序列化器:碰到Monolog、Cache这类带资源的类,直接跳过序列化。修改config/packages/jms_serializer.yaml:jms_serializer: metadata: auto_detection: true exclusion_policy: ALL properties: # 排除HttpException里的上下文字段 Symfony\Component\HttpKernel\Exception\HttpException: properties: context: exclude: true # 直接排除整个Monolog和Cache相关类 Monolog\Logger: exclude: true Symfony\Component\Cache\Adapter\PhpFilesAdapter: exclude: true方案3:自定义异常控制器,完全掌控返回内容
要是上面的配置都满足不了你的需求,那就自己写个异常控制器,手动挑出能序列化的字段返回:
先在config/packages/fos_rest.yaml指定自定义控制器:fos_rest: exception: exception_controller: 'App\Controller\CustomExceptionController::showAction'然后创建
src/Controller/CustomExceptionController.php:<?php namespace App\Controller; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Throwable; class CustomExceptionController { public function showAction(Throwable $exception): JsonResponse { $responseData = [ 'message' => $exception->getMessage(), 'status_code' => $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500, // 只加你确定能安全序列化的字段,别碰context或trace里的服务对象 ]; return new JsonResponse($responseData, $responseData['status_code']); } }
另外你可以先自查下:是不是代码里throw异常时,不小心把Logger、Cache这类服务当成上下文参数传进去了?要是的话,直接改掉传参,这才是最根源的解决办法。
内容的提问来源于stack exchange,提问作者psylo66

