retrofit fails to parse inner json objects

Viewed 24

this is the model class to parse the json string coming from the server. when I use this class, network response fails but I can see the post in the logcat. I think retrofit cannot parse the inner objects.

public class ProfileResponse {
@SerializedName("result")
private int result;

@SerializedName("comment")
private String comment;

@SerializedName("time")
private String time;

@SerializedName("header")
private Header header;

@SerializedName("tests")
private Test[] tests;

@SerializedName("entries")
private Entry[] entries;
}

when I change this class' fields to string like below and parse them after with Gson keeping everything the same(like the Header, Entry, Test class'. I do not share them for simplicity), there is not a single problem. However I cannot understand why this happens.

public class ProfileResponse {
@SerializedName("result")
private int result;

@SerializedName("comment")
private String comment;

@SerializedName("time")
private String time;

@SerializedName("header")
private String header;

@SerializedName("tests")
private String tests;

@SerializedName("entries")
private String entries;
}

Whern I parse the response like this, there is not a problem but retrofit does not do it interrnally, I searched the similar questions and compared my models with the answers but I could not figıre out why this happens.

         String testString = profileDataString.getTests();
         Test[] tests = gson.fromJson(testString, Test[].class);

The above code works perfectly but again I want to it internally with retrofit.I do not want to parse every single fields separately, I want to receive the server response in a single object of class Profile response. What should I do? Thanks in advance,

Tese are other model class'

public class Test {
//member variables
@SerializedName("date")
private String date;

@SerializedName("lessonNo")
private int lessonNo;

@SerializedName("testNo")
private int testNo;

@SerializedName("correct")
private int correctAnswers;

@SerializedName("wrong")
private int wrongAnswers;
//getters
}
public class Entry {
//member variables
@SerializedName("subjectID")
private int subjectID;

@SerializedName("commentID")
private int commentID;

@SerializedName("comment")
private String comment;

@SerializedName("dateTS")
private String dateTime;

@SerializedName("usercode")
private int userCode;

@SerializedName("nickname")
private String nickName;

@SerializedName("likepoint")
private int likePoint;

@SerializedName("dislikepoint")
private int dislikePoint;

@SerializedName("subjectName")
private String subjectName;
//getters
}

public class Header {
//member variables
@SerializedName("nickname")
private String nickName;

@SerializedName("profilephoto")
private String profilePhoto;

@SerializedName("totalTests")
private int totalTests;

@SerializedName("totalChallenges")
private int totalChallenges;

@SerializedName("totalpoints")
private int totalPoints;

@SerializedName("socialearned")
private int socialEarned;
//getters
}

This is the singleton to get a retrofit instance

public class ApiClientRetrofit {
private static Retrofit retrofit = null;

public static Retrofit getInstance() {
    if (retrofit == null) {
        //Http logging interceptor
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(httpLoggingInterceptor)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(SERVER_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .client(okHttpClient)
                .build();
    }
    return retrofit;
}
}

and this is the activity where I make the network call

    Retrofit retrofit=ApiClientRetrofit.getInstance();
    ServerApiInterface service=retrofit.create(ServerApiInterface.class);
    Call<ProfileResponse> call = service.loadProfile(101,0,0,10,10,1);
    call.enqueue(new Callback<ProfileResponse>() {
        @Override
        public void onResponse(Call<ProfileResponse> call, Response<ProfileResponse> response) {
            if(response.isSuccessful()){
                Log.i(TAG, "onResponse: response is successful");
            }
        }

        @Override
        public void onFailure(Call<ProfileResponse> call, Throwable t) {
            Log.i(TAG, "onFailure: ");
        }
    });

finally, this is the interface that Retrofit implements to make request

public interface ServerApiInterface {
@FormUrlEncoded
@POST(ServerAdress.PROFILE_PHP)
Call<ProfileResponse> loadProfile(@Field("usercode") int userCode,
                                        @Field("testStart") int testStart,
                                        @Field("entryStart") int entryStart,
                                        @Field("entryCount") int entryCount,
                                        @Field("testCount") int testCount,
                                        @Field("header") int header);
       }
1 Answers

I may be able to help, but what does your test, header, and entries model classes look like? I would also be interested in seeing your retrofit call itself, if able.

One thing to try, I don't use array types for my models in retrofit, but I use List<my_type>. I am not too clear on if that could be the issue, but something you may want to try?

Related