Сбой в десериализации списка объектов имеет список Json с помощью Gson при использовании retrofit2 для получения данных android

#android #json #android-asynctask #gson #retrofit2

#Android #json #android-asynctask #gson #retrofit2

Вопрос:

Я просто новичок в json и модернизации и хочу получить файл json с сервера в свой список.

У меня есть класс вопросов

 public class Question {
    private String label;
    private ArrayList<String> question;

    public Question(String label) {
        this.label = label;
    }
    public String getLabel() {
        return label;
    }

    public void setQuestion(ArrayList<String> question) {
        this.question = question;
    }

    public ArrayList<String> getQuestion() {
        return question;
    }

    @Override
    public String toString() {
        String s = "Label: "   label;
        for (String t : question) {
            s  = "n"   t;
        }
        return s;
    }
}
  

Я использую Retrofit2 для настройки Api для получения объекта

 public interface ServiceApi {

@GET("/bins/{id}?pretty=1")
Call<Object> getJson(@Path("id") String id);

}
  

Вот моя задача данных, которая реализует интерфейс

 public class DataTask {
private static final String API_BASE_URL = "https://api.myjson.com";
private static final String TAG = "DataTask";
private static ServiceApi serviceApi;

public DataTask() {
    createApi();
}

private void createApi() {
    OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
    Retrofit.Builder builder = new Retrofit.Builder()
            .baseUrl(API_BASE_URL).addConverterFactory(GsonConverterFactory.create());
    Retrofit retrofit = builder.client(httpClient.build()).build();

    serviceApi = retrofit.create(ServiceApi.class);
}


public static String getJson(String id) {
        String t = null;
        Call<Object> response = serviceApi.getJson(id);
        try {
            t = response.execute().body().toString();
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        }
        Log.d(TAG, "GET Success: "   t);
        return t;
    }

}
  

Вот моя основная особенность

 public class MainActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final List<Question>[] questions = new List[1];
    final String[] s = new String[1];
    new AsyncTask<Void, Void, Void>() {

        @Override
        protected Void doInBackground(Void... params) {
            new DataTask();
            s[0] = DataTask.getJson("2yf1q");
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            questions[0] = new Gson().fromJson(s[0], new TypeToken<List<Question>>() {
            }.getType());
            Log.d(TAG, String.valueOf(questions[0].toString()));
            for (Question q : questions[0]) {
                Log.d(TAG, q.toString());
            }
        }
    }.execute();
}

}
  

И вот моя ссылка Json https://api.myjson.com/bins/2yf1q?pretty=1

При запуске я получил это исключение

 com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated array at line 1 column 30 path $[0].question[1]
                                                   at com.google.gson.Gson.fromJson(Gson.java:902)
                                                   at com.google.gson.Gson.fromJson(Gson.java:852)
                                                   at com.google.gson.Gson.fromJson(Gson.java:801)
                                                   at svmc.anthao.MainActivity$1.onPostExecute(MainActivity.java:49)
                                                   at svmc.anthao.MainActivity$1.onPostExecute(MainActivity.java:36)
                                                   at android.os.AsyncTask.finish(AsyncTask.java:632)
                                                   at android.os.AsyncTask.access$600(AsyncTask.java:177)
                                                   at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
                                                   at android.os.Handler.dispatchMessage(Handler.java:102)
                                                   at android.os.Looper.loop(Looper.java:149)
                                                   at android.app.ActivityThread.main(ActivityThread.java:5268)
                                                   at java.lang.reflect.Method.invokeNative(Native Method)
                                                   at java.lang.reflect.Method.invoke(Method.java:515)
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
                                                   at dalvik.system.NativeStart.main(Native Method)
  

Я не понимаю, как это может быть.
Пожалуйста, помогите мне исправить это, большое вам спасибо

Комментарии:

1. Попробуйте создать возвращаемый тип вашего модифицированного вызова<Вопрос>

2. спасибо @FilipeEsperandio за ответ, я пытался, но получил то же исключение

Ответ №1:

Пришлось поиграть с вашим API, чтобы реализовать это. Конечная точка возвращает массив, а не объект, поэтому ваш модифицированный интерфейс должен быть:

 @GET("/bins/{id}?pretty=1")
Call<List<Question>> getJson(@Path("id") String id);
  

Вот рабочий пример:

 public class SampleTest {
    public class Question {
        private String label;
        private ArrayList<String> question;

        public Question(String label) {
            this.label = label;
        }
        public String getLabel() {
            return label;
        }

        public void setQuestion(ArrayList<String> question) {
            this.question = question;
        }

        public ArrayList<String> getQuestion() {
            return question;
        }

        @Override
        public String toString() {
            String s = "Label: "   label;
            for (String t : question) {
                s  = "n"   t;
            }
            return s;
        }
    }

    public interface ServiceApi {

        @GET("/bins/{id}?pretty=1")
        Call<List<Question>> getJson(@Path("id") String id);

    }

    private static final String API_BASE_URL = "https://api.myjson.com";

    @Test
    public void restCall() throws Exception {
        OkHttpClient httpClient = new OkHttpClient();
        Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl(API_BASE_URL).addConverterFactory(GsonConverterFactory.create());
        Retrofit retrofit = builder.client(httpClient).build();

        ServiceApi serviceApi = retrofit.create(ServiceApi.class);
        Call<List<Question>> call = serviceApi.getJson("2yf1q");
        List<Question> questions = call.execute().body();

        assertThat(questions, notNullValue());
    }
}