Android Studio中Gson解析无逗号JSON数组及Ticketmaster API位置获取问题
嘿,我来帮你搞定这两个问题,一步步来:
1. 如何在Android Studio中使用Gson解析未以逗号分隔数组的JSON字符串?
这种无逗号分隔的数组(比如格式类似 ["item1""item2""item3"])不属于标准JSON,Gson默认没法直接解析,得自定义一个TypeAdapter来处理这种特殊格式。
步骤如下:
创建自定义TypeAdapter
这个适配器会先把输入的非标准JSON处理成逗号分隔的标准格式,再交给Gson解析。示例代码:import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class NoCommaArrayAdapter extends TypeAdapter<List<String>> { @Override public void write(JsonWriter out, List<String> value) throws IOException { // 写入时按标准数组格式输出 out.beginArray(); for (String s : value) { out.value(s); } out.endArray(); } @Override public List<String> read(JsonReader in) throws IOException { List<String> list = new ArrayList<>(); in.beginArray(); // 直接读取每个字符串,忽略缺失的逗号 while (in.peek() != JsonToken.END_ARRAY) { list.add(in.nextString()); } in.endArray(); return list; } }如果是更复杂的对象数组,也可以先获取原始JSON串,手动修复格式后再解析:
String rawJson = "..."; // 你的无逗号数组JSON // 把连续的双引号替换成",",修复为标准格式 String fixedJson = rawJson.replaceAll("\"\"", "\",\""); List<String> items = new Gson().fromJson(fixedJson, new TypeToken<List<String>>(){}.getType());注册适配器到Gson
在创建Gson实例时,把自定义适配器注册进去,之后就能用它解析非标准数组了:Gson gson = new GsonBuilder() .registerTypeAdapter(new TypeToken<List<String>>(){}.getType(), new NoCommaArrayAdapter()) .create(); // 解析你的非标准JSON字符串 List<String> result = gson.fromJson(yourNonCommaJson, new TypeToken<List<String>>(){}.getType());
2. 从Ticketmaster API的JSON中获取位置信息
你遇到的问题大概率是实体类的嵌套结构没和JSON对应上,或者下划线命名的字段没做正确映射。我们需要严格按照JSON的层级来创建实体类:
第一步:创建匹配的实体类
按照JSON的嵌套层级,我们需要以下几个类(可以用内部类简化结构):
最外层根类(比如叫
TicketmasterResponse):public class TicketmasterResponse { @SerializedName("_embedded") private EmbeddedRoot embeddedRoot; // getter和setter public EmbeddedRoot getEmbeddedRoot() { return embeddedRoot; } public void setEmbeddedRoot(EmbeddedRoot embeddedRoot) { this.embeddedRoot = embeddedRoot; } }EmbeddedRoot类(对应外层的
_embedded):public class EmbeddedRoot { private List<Event> events; // getter和setter public List<Event> getEvents() { return events; } public void setEvents(List<Event> events) { this.events = events; } }Event类(对应数组里的event对象):
public class Event { private String name; private String id; @SerializedName("_embedded") private EmbeddedEvent embeddedEvent; // getter和setter public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public EmbeddedEvent getEmbeddedEvent() { return embeddedEvent; } public void setEmbeddedEvent(EmbeddedEvent embeddedEvent) { this.embeddedEvent = embeddedEvent; } }EmbeddedEvent类(对应event里的
_embedded):public class EmbeddedEvent { private List<Venue> venues; // getter和setter public List<Venue> getVenues() { return venues; } public void setVenues(List<Venue> venues) { this.venues = venues; } }Venue类和Location类:
public class Venue { private String name; private Location location; // getter和setter public String getName() { return name; } public void setName(String name) { this.name = name; } public Location getLocation() { return location; } public void setLocation(Location location) { this.location = location; } } public class Location { private String longitude; private String latitude; // getter和setter public String getLongitude() { return longitude; } public void setLongitude(String longitude) { this.longitude = longitude; } public String getLatitude() { return latitude; } public void setLatitude(String latitude) { this.latitude = latitude; } }
第二步:解析并获取位置信息
用Gson解析后,逐层获取到location:
// 假设你已经拿到了API返回的JSON字符串 String apiJson = "..."; Gson gson = new Gson(); TicketmasterResponse response = gson.fromJson(apiJson, TicketmasterResponse.class); // 逐层获取经纬度信息 if (response != null && response.getEmbeddedRoot() != null) { List<Event> events = response.getEmbeddedRoot().getEvents(); if (events != null && !events.isEmpty()) { Event firstEvent = events.get(0); if (firstEvent.getEmbeddedEvent() != null) { List<Venue> venues = firstEvent.getEmbeddedEvent().getVenues(); if (venues != null && !venues.isEmpty()) { Venue firstVenue = venues.get(0); Location location = firstVenue.getLocation(); if (location != null) { String longitude = location.getLongitude(); String latitude = location.getLatitude(); // 这里就成功拿到经纬度了 Log.d("Location", "经度: " + longitude + ", 纬度: " + latitude); } } } } }
关键注意点:
- 所有带下划线的字段(比如
_embedded)必须用@SerializedName("_embedded")注解映射,因为Java不允许下划线开头的变量名,Gson默认按驼峰匹配,所以必须显式指定对应关系。 - 嵌套类的层级必须和JSON完全一致,少一层或者字段名不匹配都会导致解析后属性为null。
内容的提问来源于stack exchange,提问作者Cristina Racoviţă
相关产品推荐
相关产品推荐

