Symfony中使用JMS Serializer实现对象序列化子分组是否可行?
JMS Serializer 自定义嵌套序列化分组方案
结论
JMS Serializer 完全支持你需要的子分组嵌套序列化效果,无需修改原有业务逻辑,常用实现方案如下:
注:你提供的目标JSON存在两处笔误:
releaseInformation应为JSON对象(外层用{}而非[]),relaseInformation拼写缺失字母e。
方案1:虚拟属性注解(最简便)
该方案无需修改原有类的字段结构,仅需通过注解配置序列化规则即可:
- 首先对原有三个
release*字段标记排除序列化 - 新增虚拟方法返回嵌套结构的内容,指定序列化后的字段名
代码示例:
<?php use JMS\Serializer\Annotation\Exclude; use JMS\Serializer\Annotation\VirtualProperty; use JMS\Serializer\Annotation\SerializedName; class Book { public string $title; /** * @Exclude */ public int $releaseYear; /** * @Exclude */ public int $releaseDay; /** * @Exclude */ public int $releaseMonth; /** * @VirtualProperty * @SerializedName("releaseInformation") */ public function getReleaseInfo(): array { return [ 'releaseYear' => $this->releaseYear, 'releaseDay' => $this->releaseDay, 'releaseMonth' => $this->releaseMonth ]; } }
序列化后输出的JSON结构如下:
{ "title": "Example", "releaseInformation": { "releaseYear": 2021, "releaseDay": 14, "releaseMonth": 8 } }
方案2:序列化事件监听器(无侵入)
如果不想修改原实体类的代码,可以通过JMS的序列化事件实现:
- 注册事件监听器监听
serializer.pre_serialize事件 - 事件触发时动态向序列化数据中添加
releaseInformation字段 - 同时隐藏原有的三个
release*字段
该方案适合实体类不允许修改的场景。
方案3:值对象嵌套(规范方案)
如果业务允许调整实体结构,更推荐单独定义ReleaseInformation值对象,在Book类中关联该对象并通过@Type注解指定类型,这种方式支持正反序列化,维护性更高。
内容的提问来源于stack exchange,提问作者DerHaendler
相关产品推荐
相关产品推荐

