Spring Boot使用RestTemplate消费含无名嵌套JSON数组的API问题
解决Spring Boot中无名称键值对的JSON映射问题
嗨,我刚好遇到过类似的场景,给你几个实用的解决方案:
首先先假设你的API返回的JSON结构大概是这样的(方便后续举例):
{
"playerentry": [
{"勒布朗·詹姆斯": "洛杉矶湖人"},
{"凯文·杜兰特": "菲尼克斯太阳"}
]
}
方案1:用List<Map<String, Object>>直接接收
这是最快速的实现方式,因为Map天然适合存储这种无固定键名的键值对。你只需要创建顶层的响应类:
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; import java.util.Map; public class PlayerApiResponse { @JsonProperty("playerentry") private List<Map<String, String>> playerEntries; // 别忘了添加getter和setter方法 public List<Map<String, String>> getPlayerEntries() { return playerEntries; } public void setPlayerEntries(List<Map<String, String>> playerEntries) { this.playerEntries = playerEntries; } }
之后调用API解析的时候,直接用这个类接收就行:
RestTemplate restTemplate = new RestTemplate(); PlayerApiResponse response = restTemplate.getForObject("你的API地址", PlayerApiResponse.class); // 遍历获取球员和球队信息 for (Map<String, String> entry : response.getPlayerEntries()) { for (Map.Entry<String, String> playerTeam : entry.entrySet()) { String playerName = playerTeam.getKey(); String teamName = playerTeam.getValue(); // 这里处理你的业务逻辑 System.out.println("球员:" + playerName + ",球队:" + teamName); } }
方案2:用@JsonAnySetter实现面向对象的映射
如果想让代码更优雅,符合面向对象的设计,可以自定义一个PlayerEntry类,用Jackson的@JsonAnySetter注解来捕获无名称的键值对:
import com.fasterxml.jackson.annotation.JsonAnySetter; public class PlayerEntry { private String playerName; private String teamName; @JsonAnySetter public void mapPlayerTeam(String key, String value) { this.playerName = key; this.teamName = value; } // getter和setter public String getPlayerName() { return playerName; } public void setPlayerName(String playerName) { this.playerName = playerName; } public String getTeamName() { return teamName; } public void setTeamName(String teamName) { this.teamName = teamName; } }
然后修改顶层响应类,把List<Map<...>>换成List<PlayerEntry>:
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class PlayerApiResponse { @JsonProperty("playerentry") private List<PlayerEntry> playerEntries; // getter和setter public List<PlayerEntry> getPlayerEntries() { return playerEntries; } public void setPlayerEntries(List<PlayerEntry> playerEntries) { this.playerEntries = playerEntries; } }
这样解析后,你可以直接通过PlayerEntry的getter获取数据,不用再遍历Map:
for (PlayerEntry entry : response.getPlayerEntries()) { System.out.println("球员:" + entry.getPlayerName() + ",球队:" + entry.getTeamName()); }
补充说明
这两种方案都依赖Spring默认的Jackson JSON处理器,不管你用RestTemplate还是WebClient,都能直接生效。如果你的API返回的每个数组元素里有多个无名称键值对,也可以调整PlayerEntry类,用一个Map来存储所有键值对,只需要把@JsonAnySetter的逻辑改成往Map里存值就行。
内容的提问来源于stack exchange,提问作者Flypkey
相关产品推荐
相关产品推荐

