Fastjson1.2.7 解析 GraphQL 泛型 DTO 时,Edge<T>
的 node
被反序列化成错误的类型(例如 ShopifyOrder)——有人遇到过吗?
问题背景
我在对接 Shopify GraphQL Admin API 时,需要解析 FulfillmentOrder
相关数据,GraphQL 的返回结构是标准的 Relay Connection 模式:
order(id: $id) { id fulfillmentOrders(first: 10) { edges { node { id status lineItems(first: 50) { edges { node { id remainingQuantity } } } } } }}
为了对应这个结构,我在 Java 里定义了通用的 DTO:
public class Connection<T> { private List<Edge<T>> edges; private PageInfo pageInfo; // getter / setter } public class Edge<T> { private T node; private String cursor; // getter / setter }
GetFOResponse
/ OrderFulfillment
/ FulfillmentOrderNode
等类的字段也都写成了 private + getter/setter,并且所有地方都带了明确泛型:
Connection<FulfillmentOrderNode>
Connection<FOLI>
解析代码:
GraphQLResponse<GetFOResponse> foParsed = JSON.parseObject( getFoResp, new TypeReference<GraphQLResponse<GetFOResponse>>() {} );
遇到的问题
无论我怎么改 DTO,Edge<FulfillmentOrderNode>.getNode()
解析出来的对象却总是 ShopifyOrder
(调用拉单API时候,Edge<T>里面的泛型就是ShopifyOrder,我怀疑就是fastjson的反序列化缓存了
)。
现象:
node.getClass()
=ShopifyOrder
字段除了
id
外基本都是null
也就是说 Fastjson 在反序列化时 完全忽略了泛型
T=FulfillmentOrderNode
,而是拿了项目里另一个名字相近的类来填。
我尝试过:
所有字段改为 private,只保留 getter/setter(避免 public 字段被直接赋值)
所有 DTO 不再使用原始类型(禁止
List<Edge>
/Connection
,必须List<Edge<FOLI>>
/Connection<FulfillmentOrderNode>
)使用
Feature.DisableASM
禁用 ASM 缓存
现在怀疑:Fastjson 似乎在第一次遇到 Edge<T>
的时候,就缓存了反序列化器,后面所有 Edge<T>
都会按第一次的类型来反序列化。