从YuGiOh! API获取JSON映射为Java Card类的问题求助
问题解决:游戏王卡牌API JSON映射至自定义类
核心问题分析
- JSON结构不匹配:API返回的是包含
data数组的顶层对象,而非直接的卡牌数组,直接反序列化成card[]会触发类型不匹配错误。 - 自定义类存在错误:
- 违反Java命名规范,类名未大写
setName方法参数与赋值逻辑错误- 缺少Jackson反序列化必需的无参构造函数
- 图片路径字段未对应API中的
card_images[0].image_url节点
修正方案
1. 修复自定义Card类
package card; public class Card { private int atk; private int def; private int level; private String race; private String attribute; private String archetype; private String imagePath; private String name; // Jackson反序列化必需的无参构造 public Card() {} // 带参构造(可选) public Card(int atk, int def, int level, String name, String attribute, String imagePath) { this.atk = atk; this.def = def; this.level = level; this.attribute = attribute; this.imagePath = imagePath; this.name = name; } // Getter & Setter public int getAtk() { return atk; } public void setAtk(int atk) { this.atk = atk; } public int getDef() { return def; } public void setDef(int def) { this.def = def; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } public String getRace() { return race; } public void setRace(String race) { this.race = race; } public String getAttribute() { return attribute; } public void setAttribute(String attribute) { this.attribute = attribute; } public String getArchetype() { return archetype; } public void setArchetype(String archetype) { this.archetype = archetype; } public String getImagePath() { return imagePath; } public void setImagePath(String imagePath) { this.imagePath = imagePath; } public String getName() { return name; } // 修复setName方法错误 public void setName(String name) { this.name = name; } }
2. 创建API响应包装类
用于匹配API返回的顶层JSON结构:
package card; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class CardResponse { @JsonProperty("data") private List<Card> data; public List<Card> getData() { return data; } public void setData(List<Card> data) { this.data = data; } }
3. 修正API请求与反序列化逻辑
解决流只能读取一次的问题,同时提取图片路径:
import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import java.io.InputStream; import java.nio.charset.StandardCharsets; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.JsonNode; import card.Card; import card.CardResponse; public class API { public void searchCard() { try { URL url = new URL("https://db.ygoprodeck.com/api/v7/cardinfo.php?name=Dark%"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.connect(); int responseCode = conn.getResponseCode(); if (responseCode != 200) { throw new RuntimeException("HttpResponseCode: " + responseCode); } else { // 将流转为字符串,避免重复读取问题 InputStream inputStream = conn.getInputStream(); String jsonStr = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); inputStream.close(); ObjectMapper mapper = new ObjectMapper(); // 反序列化顶层响应对象 CardResponse response = mapper.readValue(jsonStr, CardResponse.class); List<Card> cardList = response.getData(); // 提取每个卡牌的图片路径 JsonNode rootNode = mapper.readTree(jsonStr); JsonNode dataNode = rootNode.path("data"); for (int i = 0; i < cardList.size(); i++) { Card card = cardList.get(i); JsonNode cardDataNode = dataNode.get(i); // 从card_images数组第一个元素获取image_url String imageUrl = cardDataNode.path("card_images").get(0).path("image_url").asText(); card.setImagePath(imageUrl); // 测试输出 System.out.printf("卡牌:%s,攻击力:%d,图片地址:%s%n", card.getName(), card.getAtk(), card.getImagePath()); } } } catch (Exception e) { e.printStackTrace(); } } }
关键说明
- 必须通过
CardResponse接收API返回的顶层对象,再提取内部的data数组 - 确保自定义类符合JavaBean规范(无参构造、正确的Getter/Setter)
- 图片路径需要从API返回的嵌套节点中手动提取,或通过自定义Jackson反序列化器实现自动映射
内容的提问来源于stack exchange,提问作者Lyna DJELMOUDI
相关产品推荐
相关产品推荐

