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

Spring WebClient调用GraphQL服务时如何在HTTP 200状态下获取错误响应体

解决方案

方案1:通过通用GraphQL响应包装类处理(推荐)

核心思路:先定义符合GraphQL响应规范的通用包装实体,先将响应解析为该包装类,判断errors字段是否存在且非空,存在则处理错误,否则提取data字段转换为目标类型。
首先定义相关实体类:

// GraphQL错误信息实体
@Data
public class GraphQLError {
    private String message;
    private List<Map<String, Integer>> locations;
    private Map<String, Object> extensions;
}
// 通用GraphQL响应包装类
@Data
public class GraphQLResponse<T> {
    private List<GraphQLError> errors;
    private T data;
}

改造后的WebClient通用调用方法:

public <T> Mono<T> callGraphQLService(Object graphQLQuery, Class<T> classType) {
    // 构造带泛型的ParameterizedTypeReference,用于解析通用响应包装类
    ParameterizedTypeReference<GraphQLResponse<T>> responseType = 
        new ParameterizedTypeReference<GraphQLResponse<T>>() {};

    return webClient()
        .post()
        .bodyValue(graphQLQuery)
        .retrieve()
        .bodyToMono(responseType)
        .flatMap(response -> {
            // 判断是否存在错误
            if (response.getErrors() != null && !response.getErrors().isEmpty()) {
                // 此处可自定义异常,把errors信息带入,方便上层处理
                return Mono.error(new GraphQLServiceException(response.getErrors()));
            }
            // 无错误直接返回业务数据
            return Mono.just(response.getData());
        });
}

方案2:通过JsonNode动态判断(无需额外定义实体)

如果不想新增GraphQL相关实体类,可以先将响应解析为JsonNode,动态判断errors节点是否存在:

public <T> Mono<T> callGraphQLService(Object graphQLQuery, Class<T> classType) {
    ObjectMapper objectMapper = new ObjectMapper();
    return webClient()
        .post()
        .bodyValue(graphQLQuery)
        .retrieve()
        .bodyToMono(JsonNode.class)
        .flatMap(jsonNode -> {
            // 判断是否存在errors节点且非空
            if (jsonNode.has("errors") && !jsonNode.get("errors").isEmpty()) {
                // 提取错误信息抛出自定义异常
                String errorMsg = jsonNode.get("errors").get(0).get("message").asText();
                return Mono.error(new RuntimeException("GraphQL调用错误:" + errorMsg));
            }
            // 将data节点转换为目标类型
            T data = objectMapper.convertValue(jsonNode.get("data"), classType);
            return Mono.just(data);
        });
}

两种方案都不需要依赖HTTP状态码,完全基于响应体内容做错误判断,完美适配GraphQL接口200状态码返回错误的场景。方案1类型更安全,适合有大量GraphQL调用的项目;方案2更轻量,适合调用频次低的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:54:04