android - 使用带有 JsonSyntaxException 的 Retrofit 在 Android 中解析 JSON
问题描述
我在这个“解析世界”中真的很新,我知道已经有很多关于这个问题的讨论(所以如果它可能是一个重复的问题,我很抱歉),但是,即使遵循一些指南并阅读一些答案,我找不到我的问题的解决方案。
我的错误是
Expected BEGIN_OBJECT but was STRING at line 1 column 1
我需要解析的JSON如下:
[
{
"id":1,
"name":"first",
"filename":"36ba664b-769c-404f-87e2-4ee8b9ac20a2.png",
"floor":3,
"north":48.31202,
"south":48.310677,
"east":10.1578865,
"west":10.155078,
"opacity":1.0,
"level":0
},
{
"id":2,
"name":"second",
"filename":"522f79d4-0dd4-4425-9f81-70a73bdfebc6.png",
"floor":0,
"north":48.31202,
"south":48.310677,
"east":10.1578865,
"west":10.155078,
"opacity":1.0,
"level":0
},
{
"id":3,
"name":"third",
"filename":"00e10310-739a-407e-86b0-373ba71144e1.png",
"floor":0,
"north":53.02099,
"south":53.02067,
"east":-1.4836869,
"west":-1.4843831,
"opacity":1.0,
"level":0
}
]
所以,按照本指南:http ://www.androiddeft.com/retrofit-android/ 我创建了两个类:
数据和数据列表:
public class Data{
@SerializedName("id")
@Expose
private Integer id;
@SerializedName("name")
@Expose
private String name;
@SerializedName("filename")
@Expose
private String filename;
@SerializedName("floor")
@Expose
private Integer floor;
@SerializedName("north")
@Expose
private Double north;
@SerializedName("south")
@Expose
private Double south;
@SerializedName("east")
@Expose
private Double east;
@SerializedName("west")
@Expose
private Double west;
@SerializedName("opacity")
@Expose
private Double opacity;
@SerializedName("level")
@Expose
private Integer level;
}
public class DataList{
private ArrayList<Data> data = null;
public ArrayList<Data> getData() {
return data;
}
}
在我创建了 API 服务和改造客户端之后:
public interface DataApiService {
@GET("/")
Call<DataList> getMyJSON();
}
public class DataRequestManager {
private static String baseUrl = "mylink";
private static Retrofit getRetrofitInstance() {
Gson gson = new GsonBuilder()
.setLenient()
//.enableComplexMapKeySerialization()
.create();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
if (BuildConfig.DEBUG) {
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
} else {
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
}
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.connectTimeout(10, TimeUnit.SECONDS);
httpClient.readTimeout(20, TimeUnit.SECONDS);
httpClient.writeTimeout(20, TimeUnit.SECONDS);
httpClient.addInterceptor(logging);
OkHttpClient debuggclient = httpClient.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(new NullOnEmptyConverterFactory())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(debuggclient).build();
return retrofit;
}
public static DataApiService getApiService() {
return getRetrofitInstance().create(DataApiService.class);
}
}
但是当我这样做时:
private static List<Data> dataList;
DataApiService api = DataRequestManager.getApiService();
Call<DataList> call = api.getMyJSON();
call.enqueue(new Callback<DatasList>() {
@Override
public void onResponse(Call<DatasList> call, Response<DatasList> response) {
if (response.isSuccessful()) {
//Got Successfully
dataList = response.body().getData();
}
}
@Override
public void onFailure(Call<DataList> call, Throwable t) {
Toast.makeText(context, "Parsing Data Failed"+t.getMessage(),
Toast.LENGTH_LONG).show();
}
});
该应用程序给了我 JsonSyntaxEception:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: 预期 BEGIN_OBJECT 但在第 1 行第 1 列路径 $
解决方案
你犯了一个非常基本的错误,你必须根据你的 json 更新你的界面:
public interface DataApiService {
@GET("/")
Call<List<Data>> getMyJSON();
}
您期待响应并像这样解析它:
{
"data": [
{ .. }
]
}
但实际反应是这样的:
[
{ .. }
]
更新:
在您的错误Expected BEGIN_ARRAY but was STRING at line 1 column 1
中,显然意味着您收到如下响应:
"[
{
...
}
]"
而不是这个:
[
{
...
}
]
我已将您的 Json 粘贴到编辑器中:
正如您在左下角Ln: 1 Col: 1
看到的那样,在 Json 的开头看到光标在这里[
,您会收到错误,因为您期望像数组一样[{...}]
但实际响应是"[{...}]"
只是为了证明我的观点,像这样更新你的界面:
public interface DataApiService {
@GET("/")
Call<String> getMyJSON();
}
你不会得到错误。
更多信息可以在这里找到
推荐阅读
- react-native - 错误 reactotron createStore is not function
- laravel - 使用 Carbon laravel 的意外数据 \r\n
- azure-devops - 使用 Azure Devops 和发布变量的 App.Exe 配置转换
- spring - Spring:如何在@Scheduled 注解中提供特定的属性文件?
- javascript - 如何删除所有重复的数组元素,只留下单个值?
- javascript - Vuetify - 鼠标悬停时下拉菜单不突出显示
- android - 从Android Q中的特定文件夹获取文件列表
- javascript - Payload passed to dataProvider doesn't contain File from ImageInput [3.0.0-alpha only]
- wordpress - 卸载后如何完成删除WPMU DEV插件所做的更改?
- python - 如何从命令行在 ubuntu 中查找机器生成的 PDF 的 DPI