Fastjson1.2.7 泛型反序列化错误。

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,而是拿了项目里另一个名字相近的类来填。

我尝试过:

  1. 所有字段改为 private,只保留 getter/setter(避免 public 字段被直接赋值) 

  2. 所有 DTO 不再使用原始类型(禁止 List<Edge> / Connection,必须 List<Edge<FOLI>> / Connection<FulfillmentOrderNode>

  3. 使用 Feature.DisableASM 禁用 ASM 缓存 


现在怀疑:Fastjson 似乎在第一次遇到 Edge<T> 的时候,就缓存了反序列化器,后面所有 Edge<T> 都会按第一次的类型来反序列化。


评论区

热门反馈

扫码入社