GSON无法解析Zomato餐厅集合,Java+Akka开发解析问题求助
解决Zomato API响应解析的问题
嘿,我之前也踩过Zomato API解析的坑,你的情况我太熟悉了!核心问题在于你没注意到API返回的JSON结构有一层额外嵌套——restaurants数组里的每一项并不是直接的Restaurant对象,而是被包裹在restaurant字段里的。下面一步步帮你搞定:
1. 调整实体类结构
你需要新增两个辅助类来匹配JSON的层级,和你现有的Restaurant类配合使用:
顶层响应类(ZomatoRestaurantResponse)
对应整个API返回的根JSON对象:
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class ZomatoRestaurantResponse { @JsonProperty("results_found") private int resultsFound; @JsonProperty("results_start") private int resultsStart; @JsonProperty("results_shown") private int resultsShown; @JsonProperty("restaurants") private List<RestaurantWrapper> restaurants; // 生成getter、setter,或者用Lombok的@Data注解简化代码 }
餐厅包装类(RestaurantWrapper)
用来匹配数组里的嵌套restaurant字段:
import com.fasterxml.jackson.annotation.JsonProperty; public class RestaurantWrapper { @JsonProperty("restaurant") private Restaurant restaurant; // getter、setter }
你的现有Restaurant类
只需要确保字段和JSON中restaurant对象的键一一对应,用@JsonProperty处理蛇形命名和驼峰命名的转换,比如:
import com.fasterxml.jackson.annotation.JsonProperty; public class Restaurant { @JsonProperty("id") private String id; @JsonProperty("name") private String name; @JsonProperty("location") private Location location; @JsonProperty("cuisines") private String cuisines; @JsonProperty("average_cost_for_two") private int averageCostForTwo; @JsonProperty("user_rating") private UserRating userRating; // 其他字段按需添加:thumb、menu_url等 // 记得给Location、UserRating这类嵌套对象创建对应的实体类 // getter、setter }
举个Location类的示例:
import com.fasterxml.jackson.annotation.JsonProperty; public class Location { @JsonProperty("address") private String address; @JsonProperty("city") private String city; @JsonProperty("latitude") private String latitude; @JsonProperty("longitude") private String longitude; // 其他字段和getter、setter }
2. 在Akka环境中解析JSON
如果用Akka HTTP调用API,集成Jackson模块就能自动完成反序列化:
第一步:添加依赖
确保你的Maven/Gradle里包含Akka HTTP的Jackson支持:
<!-- Maven示例,替换成你的Akka版本 --> <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-http-jackson_2.13</artifactId> <version>10.5.2</version> </dependency>
第二步:解析响应的代码示例
在Akka HTTP请求逻辑中,这样把响应体转成实体类:
import akka.actor.ActorSystem; import akka.http.javadsl.Http; import akka.http.javadsl.model.HttpRequest; import akka.http.javadsl.unmarshalling.Unmarshaller; import akka.stream.Materializer; import java.util.concurrent.CompletionStage; public class ZomatoApiClient { private final ActorSystem system; private final Materializer materializer; private final Http http; public ZomatoApiClient(ActorSystem system, Materializer materializer) { this.system = system; this.materializer = materializer; this.http = Http.get(system); } public CompletionStage<ZomatoRestaurantResponse> fetchRestaurants(String apiUrl) { HttpRequest request = HttpRequest.create(apiUrl) .addHeader(akka.http.javadsl.model.headers.Authorization.basic("你的Zomato API密钥", "")); return http.singleRequest(request, materializer) .thenCompose(response -> { if (response.status().isSuccess()) { return Unmarshaller.entityTo(ZomatoRestaurantResponse.class) .unmarshal(response.entity(), materializer); } else { return response.discardEntityBytes(materializer) .thenApply(done -> { throw new RuntimeException("API请求失败:" + response.status()); }); } }); } }
3. 关键注意事项
- 必须用
@JsonProperty注解映射蛇形命名(比如results_found)和Java驼峰命名,否则Jackson无法正确识别字段。 - 确保Jackson版本和Akka依赖的版本兼容,避免出现依赖冲突。
- 对于空数组字段(比如
offers),直接用List类型的字段接收即可,Jackson会自动处理空值。
这样调整后,你就能顺利解析Zomato的API响应了!
内容的提问来源于stack exchange,提问作者grzemski
相关产品推荐
相关产品推荐

