I am really new in this "parsing world" and I know that there are already a lot of discussion about this problem (so I am sorry if it can be a reepetitive question) , but, even following some guide and reading some answer, I could not find a solution to my problem.
the error that I have is
Expected BEGIN_OBJECT but was STRING at line 1 column 1
and the JSON I need to parse it is the following:
[
{
"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
}
]
so, following this guide: http://www.androiddeft.com/retrofit-android/ I created two classes:
Data and DataList:
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;
}
}
And after I created the API service and the Retrofit Client:
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);
}
}
But when I do:
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();
}
});
The application gives me the JsonSyntaxEception:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
What you are trying to do is incorrect, since your response is just an array. The json that would be acceptable for your DataList
should be:
data : [
{
"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
},...
]
This happens because when serializing it sees DataList
as nested objects, since in order to access array, you do dataList.data
.
The solution to your problem is to just replace DataList
class with List<Data>
:
Call<List<Data>> call = api.getMyJSON();
You are doing a very basic mistake you have to update your interface according to your json as:
public interface DataApiService {
@GET("/")
Call<List<Data>> getMyJSON();
}
You are expecting the response and parsing it like this:
{
"data": [
{ .. }
]
}
But Actual response is like this:
[
{ .. }
]
Update:
In your error Expected BEGIN_ARRAY but was STRING at line 1 column 1
, clearly means you are getting response this like as:
"[
{
...
}
]"
Instead of this:
[
{
...
}
]
I have paste your Json in editor:
As you can see at the bottom left Ln: 1 Col: 1
and see the cursor at the start of Json which is here [
, you are getting error because you expecting array like [{...}]
but actual response is "[{...}]"
Just to prove my point update your interface like this:
public interface DataApiService {
@GET("/")
Call<String> getMyJSON();
}
You will not get the error.
More information can be found here
I found the solution! As the main problem was the authentication, I changed my Retrofit Client code as follows:
public class DataRequestManager {
private static String baseUrl = "mylink";
//Get Retrofit Instance
private static Retrofit getRetrofitInstance(Context context) {
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
//Basic Auth
String username="myUsername";
String password="myPassword";
String authToken = null;
if (!TextUtils.isEmpty(username)
&& !TextUtils.isEmpty(password)) {
authToken = Credentials.basic(username, password);
}
//Create a new Interceptor.
final String finalAuthToken = authToken;
Interceptor headerAuthorizationInterceptor = new Interceptor() {
@Override
public okhttp3.Response intercept(Chain chain) throws IOException {
okhttp3.Request request = chain.request();
Headers headers = request.headers().newBuilder().add("Authorization", finalAuthToken).build();
request = request.newBuilder().headers(headers).build();
return chain.proceed(request);
}
};
//Add the interceptor to the client builder.
clientBuilder.addInterceptor(headerAuthorizationInterceptor);
return new Retrofit.Builder().baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(clientBuilder.build())
.build();
}
//Get API Service
public static FloorplansApiService getApiService(Context context) {
return getRetrofitInstance(context).create(FloorplansApiService.class);
}
}
and now it works! Thank you all guys!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.