You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让JMS/Serializer将属性反序列化为对象?ResponseStatus始终为数组的问题排查

问题:反序列化后ResponseStatus始终是数组而非指定对象实例

你遇到的核心问题是混用了JMS Serializer的注解,但实际使用的是Symfony Serializer组件——这两个是完全独立的库,Symfony Serializer无法识别JMS的注解规则,所以它只会把嵌套的JSON结构转换成数组,而不会自动实例化SalesOrderGetResponseStatus对象。

下面给出两种可行的解决方案:

方案一:改用JMS Serializer的官方使用方式

既然你已经定义了JMS的注解,直接使用JMS Serializer库来处理序列化/反序列化是最直接的方式:

use JMS\Serializer\SerializerBuilder;

// 正确初始化JMS Serializer实例
$serializer = SerializerBuilder::create()
    ->addDefaultHandlers() // 加载默认处理器,处理对象嵌套等场景
    ->build();

// 直接反序列化为目标类实例,无需提前创建对象
$result = $serializer->deserialize($resultJson, SalesOrderGetResponse::class, 'json');

这样JMS Serializer会正确识别你定义的@Type注解,自动将ResponseStatus对应的JSON结构转换成SalesOrderGetResponseStatus对象。

方案二:切换为Symfony Serializer的注解体系

如果你更倾向于使用Symfony Serializer,需要把JMS的注解替换为Symfony Serializer自身的注解,并确保初始化时正确加载注解支持:

1. 修改实体类的注解

更新SalesOrderGetResponse类:

use Symfony\Component\Serializer\Annotation\Type;
use Symfony\Component\Serializer\Annotation\SerializedName;

class SalesOrderGetResponse {
    /**
     * @Type("array<Vendor\Module\Model\SalesOrder>")
     * @var SalesOrder[]
     */
    public $mvSalesOrders = [];

    /**
     * @Type("Vendor\Module\Model\SalesOrderGetResponseStatus")
     * @SerializedName("ResponseStatus") // 显式声明属性与JSON键的对应关系,避免大小写等问题
     * @var SalesOrderGetResponseStatus
     */
    public $ResponseStatus;
}

更新SalesOrderGetResponseStatus类:

use Symfony\Component\Serializer\Annotation\Type;

class SalesOrderGetResponseStatus {
    const ERROR_CODE_SUCCESS = 0;

    /**
     * @Type("string")
     * @var string
     */
    public $ErrorCode;
}

2. 正确初始化Symfony Serializer

确保初始化时使用Symfony的注解加载器:

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Doctrine\Common\Annotations\AnnotationReader;

// 创建类元数据工厂,加载Symfony的注解
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
$normalizers = [new ObjectNormalizer($classMetadataFactory)];
$encoders = [new JsonEncoder()];

$serializer = new Serializer($normalizers, $encoders);

// 执行反序列化
$result = new SalesOrderGetResponse();
$serializer->deserialize($resultJson, SalesOrderGetResponse::class, 'json', [
    \Symfony\Component\Serializer\Normalizer\AbstractNormalizer::OBJECT_TO_POPULATE => $result
]);

这样Symfony Serializer就能识别@Type注解,将嵌套JSON结构转换成指定的对象实例了。

内容的提问来源于stack exchange,提问作者gabtzi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 23:52:41