Android无法读取Google Cloud部署的Flask API JSON数据求助
问题原因
你的Android端无法读取数据,核心问题是Flask API返回的JSON结构和Retrofit定义的解析模型完全不匹配,同时还有几处代码细节错误:
- JSON结构不匹配:Flask返回的JSON是外层包裹在
data字段内、内部按列分组的字典(比如userId是包含所有用户ID的键值对集合),但Retrofit期望直接解析成List<model>(用户对象数组)。 - Model类错误:Model定义了JSON不存在的
title字段,缺少city/locations的getter/setter,且无无参构造函数(Gson解析必需)。 - Retrofit接口错误:接口期望返回
Call<List<model>>,但实际API返回的是包含data字段的对象,不是直接数组。 - 未实现错误回调:你没写
onFailure方法,导致无法捕获网络或解析报错。
解决方案
第一步:修改Flask API,返回正确的JSON结构
修改Users类的get方法,将DataFrame转为按行的对象数组:
def get(self): data = pd.read_csv(users_path) # 使用orient='records'将每行转为独立对象,组成数组 return {'data': data.to_dict(orient='records')}, 200
修改后返回的JSON结构会变成:
{ "data": [ {"userId": "a1b", "name": "Joe", "city": "Paris", "locations": "['0001', '0002', '0008']"}, {"userId": "a2c", "name": "Jenny", "city": "London", "locations": "['0003', '0004']"} ] }
第二步:修复Android Model类
更新model.java,匹配JSON字段,添加无参构造和完整的getter/setter:
public class model { private String userId; private String name; private String city; private String locations; // Gson解析必需的无参构造 public model() {} public model(String userId, String name, String city, String locations) { this.userId = userId; this.name = name; this.city = city; this.locations = locations; } // 所有字段的getter和setter public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getLocations() { return locations; } public void setLocations(String locations) { this.locations = locations; } }
第三步:调整Retrofit接口与回调逻辑
- 定义外层响应包裹类,匹配API返回的
data结构:
public class UserResponse { private List<model> data; public List<model> getData() { return data; } public void setData(List<model> data) { this.data = data; } }
- 修改
myapi.java接口定义:
public interface myapi { @GET("users") Call<UserResponse> getmodels(); }
- 更新
MainActivity的回调,添加错误处理:
tv = (TextView)findViewById(R.id.tv); tv.setText(""); // 确保baseUrl以/结尾,比如"https://your-app.appspot.com/" Retrofit retrofit = new Retrofit.Builder() .baseUrl(url) .addConverterFactory(GsonConverterFactory.create()) .build(); myapi api= retrofit.create(myapi.class); Call<UserResponse> call = api.getmodels(); call.enqueue(new Callback<UserResponse>() { @Override public void onResponse(Call<UserResponse> call, Response<UserResponse> response){ if (response.isSuccessful() && response.body() != null) { List<model> data = response.body().getData(); for(int i = 0; i < data.size(); i++) { tv.append("SL No:" + data.get(i).getUserId() + "\n" + "Name:" + data.get(i).getName() + "\n" + "City:" + data.get(i).getCity() + "\n\n"); } } else { tv.setText("请求失败:" + response.message()); } } // 必须实现该方法,捕获网络或解析错误 @Override public void onFailure(Call<UserResponse> call, Throwable t) { tv.setText("请求出错:" + t.getMessage()); } });
额外检查项
- 确保
AndroidManifest.xml添加了网络权限:<uses-permission android:name="android.permission.INTERNET" /> - Android 9及以上若使用HTTP协议,需在
res/xml/network_security_config.xml配置允许明文访问,或直接使用HTTPS(推荐)。
内容的提问来源于stack exchange,提问作者haru
相关产品推荐
相关产品推荐

