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

如何使用GSON处理同一接口返回的两种不同格式的regions字段?

这问题我对接第三方API时真的碰到过,两种返回格式确实容易搞混,用适配器来统一是绝佳方案!我给你一步步拆解怎么实现:

核心思路

本质就是把两种异构的API响应,转换为一个统一的内部模型,这样后续业务代码只需要处理这个统一模型,不用关心原始API的格式差异。适配器模式正好适配这种场景——做一层格式转换的中间层。

具体实现步骤(以Java为例,其他语言思路一致)

1. 定义统一的内部模型

先不管API返回什么格式,先确定我们业务代码需要的最终数据结构:

// 业务侧统一使用的区域模型
public class Region {
    private String id;
    private String name;

    // 构造器、getter、setter按需生成
    public Region(String id, String name) {
        this.id = id;
        this.name = name;
    }

    // 省略getter、setter
}

// 统一的响应模型,包含业务需要的所有字段
public class UnifiedApiResponse {
    private String id;
    private String name;
    private List<Region> regions;

    public UnifiedApiResponse(String id, String name, List<Region> regions) {
        this.id = id;
        this.name = name;
        this.regions = regions;
    }

    // 省略getter、setter
}

2. 处理原始API的两种格式

我们需要先能解析原始的两种JSON格式,这里提供两种思路:

方式一:用DTO匹配原始格式(类型安全)

先定义对应两种返回格式的DTO,让序列化框架自动匹配:

// 对应仅返回区域ID的格式
public class SimpleRegionApiResponse {
    private Data data;

    public static class Data {
        private String id;
        private String name;
        private List<String> regions;

        // 省略getter、setter
    }
}

// 对应返回完整区域对象的格式
public class FullRegionApiResponse {
    private Data data;

    public static class Data {
        private String id;
        private String name;
        private RegionWrapper regions;

        public static class RegionWrapper {
            private List<Region> data;

            // 省略getter、setter
        }

        // 省略getter、setter
    }
}

方式二:用动态节点判断格式(更灵活)

如果API格式可能有变动,或者不想写太多DTO,可以先把JSON解析为通用的JsonNode,判断regions字段的类型:

ObjectMapper objectMapper = new ObjectMapper();
JsonNode root = objectMapper.readTree(rawJson);
JsonNode regionsNode = root.path("data").path("regions");

if (regionsNode.isArray()) {
    // 是简单格式:直接取数组里的ID
} else if (regionsNode.isObject()) {
    // 是完整格式:取对象里的data数组
} else {
    throw new IllegalArgumentException("不合法的regions格式");
}

3. 编写适配器类做统一转换

把两种格式的解析和转换逻辑封装到适配器里,对外暴露统一的转换方法:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.ArrayList;
import java.util.List;

public class RegionResponseAdapter {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 对外统一的转换方法,输入原始JSON,输出统一模型
    public static UnifiedApiResponse convert(String rawJson) throws JsonProcessingException {
        JsonNode root = objectMapper.readTree(rawJson);
        JsonNode dataNode = root.path("data");
        String id = dataNode.path("id").asText();
        String name = dataNode.path("name").asText();
        JsonNode regionsNode = dataNode.path("regions");

        List<Region> regions;
        if (regionsNode.isArray()) {
            // 处理简单格式:将ID列表转为Region对象(name设为null或空)
            regions = new ArrayList<>();
            for (JsonNode idNode : regionsNode) {
                regions.add(new Region(idNode.asText(), null));
            }
        } else if (regionsNode.isObject()) {
            // 处理完整格式:直接提取data数组转为Region列表
            regions = objectMapper.convertValue(regionsNode.path("data"), List.class);
        } else {
            throw new IllegalArgumentException("API返回的regions字段格式不支持");
        }

        return new UnifiedApiResponse(id, name, regions);
    }
}

4. 使用示例

业务代码里直接调用适配器的转换方法,拿到统一模型后就可以正常处理了:

public class Demo {
    public static void main(String[] args) throws JsonProcessingException {
        // 简单格式的API返回
        String simpleJson = "{ \"data\":{ \"id\":\"12345\", \"name\":\"Some Name\", \"regions\":[ \"r987\", \"r654\" ] } }";
        UnifiedApiResponse simpleResult = RegionResponseAdapter.convert(simpleJson);
        System.out.println(simpleResult.getRegions());

        // 完整格式的API返回
        String fullJson = "{ \"data\":{ \"id\":\"12345\", \"name\":\"Some Name\", \"regions\":{ \"data\":[ { \"id\":\"r987\", \"name\":\"region 1\" }, { \"id\":\"r654\", \"name\":\"region 2\" } ] } } }";
        UnifiedApiResponse fullResult = RegionResponseAdapter.convert(fullJson);
        System.out.println(fullResult.getRegions());
    }
}
额外提示
  • 如果是Python/JavaScript这类动态语言,思路完全一致:先判断regions的类型(数组/对象),再转换为统一的列表结构
  • 可以在适配器里加入日志,方便排查格式异常问题
  • 如果API有更多格式变种,可以在适配器里扩展判断逻辑,不影响业务代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:21:15