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

如何将第三方GraphQL响应解析并编组为Java POJO?

如何将第三方GraphQL响应编组为POJO?

我刚接触GraphQL,正在对接第三方外部服务器的GraphQL接口——已经成功发送查询并收到响应,但卡在了把响应转换成POJO或者ArrayList<POJO>这一步,而且第三方没提供GraphQL schema文件。想请教下怎么处理这个问题,有没有合适的Java库推荐?

我的GraphQL查询

query Photos($first: Int!, $propertyId: String) { 
  viewer { 
    content { 
      contentLists(first: $first, property_id: $propertyId, contentListType: IMAGE, publishState: PUBLISHED, orderBy: originalPublishDate, orderByDirection: DESC) { 
        edges { 
          node { 
            id 
            title 
            caption 
            originalPublishDate 
            lastModifiedDate 
            contents(first: $first) { 
              edges { 
                node { 
                  id 
                  title 
                  caption 
                  type 
                  ... on Image { 
                    asset { 
                      createdDate 
                      lastModifiedDate 
                      id 
                      url 
                      title 
                      height 
                      width 
                    } 
                  } 
                } 
              } 
            } 
          } 
        } 
      } 
    } 
  } 
}

查询变量

{ 
  "propertyId" : "23456832-7862-5679-4342-415f32385830", 
  "first": 20 
}

发送请求的Java代码

HttpHeaders headers = new HttpHeaders(); 
headers.setContentType(MediaType.APPLICATION_JSON); 
headers.set("Authorization", "Bearer "+accessToken); 
HttpEntity<String> entity = new HttpEntity<String>(request,headers); 
String response = restTemplate.postForObject(EXTERNAL_URL, entity, String.class);

收到的响应

{ 
  "data": { 
    "viewer": { 
      "content": { 
        "contentLists": { 
          "edges": [ 
            { 
              "node": { 
                "id": "3510e8f7-452s-f531-43b0-ac36ba979e5a9f4m", 
                "title": "Homer Simpson goes Camping", 
                "caption": "Homer Simpson goes Camping", 
                "originalPublishDate": "2018-02-18T03:31:56.352Z", 
                "lastModifiedDate": "2018-02-18T03:32:13.530Z", 
                "contents": { 
                  "edges": [ 
                    { 
                      "node": { 
                        "id": "3506d951-1332-86fg-42bc-b11183db50394f40", 
                        "title": "No Title", 
                        "caption": "", 
                        "type": "IMAGE", 
                        "asset": { 
                          "createdDate": "2018-02-18T03:31:38.406Z", 
                          "lastModifiedDate": "2018-02-18T03:31:38.991Z", 
                          "id": "65037262-7169-7065-7861-7035676a6f65323467617866", 
                          "url": "", 
                          "title": "No Title", 
                          "height": null, 
                          "width": null 
                        } 
                      } 
                    } 
                  ] 
                } 
              } 
            } 
          ] 
        } 
      } 
    } 
  }
}

当前使用的依赖

<dependency> 
  <groupId>com.graphql-java</groupId> 
  <artifactId>graphql-java</artifactId> 
  <version>8.0</version> 
</dependency> 
<dependency> 
  <groupId>com.graphql-java</groupId> 
  <artifactId>graphql-java-tools</artifactId> 
  <version>5.0.0</version> 
</dependency>

解决方案:用通用JSON解析库处理(无需schema)

因为第三方没有提供GraphQL schema,所以依赖schema的工具(比如graphql-java-tools)派不上用场。GraphQL响应本质就是标准JSON,所以用Jackson或Gson这类通用JSON解析库是最直接的方案,下面分两种场景说明:

1. 类型安全:手动创建POJO + Jackson反序列化

这种方案适合长期维护的代码,通过创建和响应结构匹配的POJO类,实现类型安全的解析。

步骤1:添加Jackson依赖(如果项目里还没有)
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version> <!-- 建议使用最新稳定版 -->
</dependency>
<!-- 如果用Java 8+的日期时间API,添加这个模块 -->
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.15.2</version>
</dependency>
步骤2:创建匹配响应结构的POJO类

根据你收到的JSON结构,逐层创建嵌套类(字段名要和JSON一致,或者用@JsonProperty映射):

// 根响应类
public class GraphQLResponse {
    private Data data;
    // Getters & Setters
}

public class Data {
    private Viewer viewer;
    // Getters & Setters
}

public class Viewer {
    private Content content;
    // Getters & Setters
}

public class Content {
    private ContentLists contentLists;
    // Getters & Setters
}

public class ContentLists {
    private List<ContentListEdge> edges;
    // Getters & Setters
}

public class ContentListEdge {
    private ContentListNode node;
    // Getters & Setters
}

public class ContentListNode {
    private String id;
    private String title;
    private String caption;
    private LocalDateTime originalPublishDate; // 用Java 8 LocalDateTime
    private LocalDateTime lastModifiedDate;
    private Contents contents;
    // Getters & Setters
}

public class Contents {
    private List<ContentEdge> edges;
    // Getters & Setters
}

public class ContentEdge {
    private ImageContentNode node;
    // Getters & Setters
}

public class ImageContentNode {
    private String id;
    private String title;
    private String caption;
    private String type;
    private Asset asset;
    // Getters & Setters
}

public class Asset {
    private LocalDateTime createdDate;
    private LocalDateTime lastModifiedDate;
    private String id;
    private String url;
    private String title;
    private Integer height;
    private Integer width;
    // Getters & Setters
}
步骤3:反序列化响应字符串
ObjectMapper objectMapper = new ObjectMapper();
// 配置支持Java 8日期时间
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
// 忽略未知字段(防止第三方更新接口加字段导致解析失败)
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

// 把响应字符串转成POJO
GraphQLResponse graphQLResponse = objectMapper.readValue(response, GraphQLResponse.class);

// 提取所有图片节点到ArrayList
List<ImageContentNode> imageList = new ArrayList<>();
graphQLResponse.getData().getViewer().getContent().getContentLists().getEdges().forEach(listEdge -> {
    listEdge.getNode().getContents().getEdges().forEach(contentEdge -> {
        imageList.add(contentEdge.getNode());
    });
});

2. 灵活解析:用JsonNode动态遍历(无需POJO)

如果只是临时处理数据,不想写大量POJO,可以用Jackson的JsonNode直接遍历JSON结构:

ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(response);

// 逐层遍历到内容节点
JsonNode contentListEdges = rootNode.path("data")
                                   .path("viewer")
                                   .path("content")
                                   .path("contentLists")
                                   .path("edges");

for (JsonNode listEdge : contentListEdges) {
    JsonNode contentListNode = listEdge.path("node");
    String listTitle = contentListNode.path("title").asText();
    
    // 遍历图片内容
    JsonNode contentEdges = contentListNode.path("contents").path("edges");
    for (JsonNode contentEdge : contentEdges) {
        JsonNode imageNode = contentEdge.path("node");
        String imageUrl = imageNode.path("asset").path("url").asText();
        // 按需处理数据
    }
}

关于GraphQL专用库的说明

因为第三方没有提供schema,graphql-java-tools这类依赖schema生成代码的工具就不适用了。而graphql-java本身主要用于构建GraphQL服务器或执行查询,不是用来解析响应的。所以通用JSON解析库(Jackson/Gson)是最适合的选择,它们足够灵活,不需要依赖schema就能处理GraphQL响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 10:09:51