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> 都会按第一次的类型来反序列化。
升级fastjson2,也可以解决。