Ожидаемый BEGIN_ARRAY, но был BEGIN_OBJECT в строке 1, путь 2, ошибка пути при использовании приложения для модификации и весенней загрузки - PullRequest
0 голосов
/ 09 февраля 2020

Я знаю, что этот вопрос задавался ранее, но мне кажется, что я пытаюсь исправить свою ошибку. Я размещаю локальный веб-сайт java, используя Spring Boot, и теперь мне нужно реализовать приложение android, используя модернизацию. Я пытаюсь выполнить простую задачу по загрузке json объектов с моего веб-сайта в представление корзины на android, но получаю следующие ошибки:

2020-02-09 12:15:57.005 9204-9274/bootcamp.entelect.co.za.supermancomicstockapp E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: bootcamp.entelect.co.za.supermancomicstockapp, PID: 9204
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:353)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
    at java.util.concurrent.FutureTask.run(FutureTask.java:271)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)
 Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
    at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:80)
    at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
    at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
    at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:117)
    at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
    at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
    at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:89)
    at bootcamp.entelect.co.za.supermancomicstockapp.Presenter.BrowsePresenter$BrowseTaskFirst.doInBackground(BrowsePresenter.java:50)
    at bootcamp.entelect.co.za.supermancomicstockapp.Presenter.BrowsePresenter$BrowseTaskFirst.doInBackground(BrowsePresenter.java:36)
    at android.os.AsyncTask$2.call(AsyncTask.java:333)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) 
    at java.lang.Thread.run(Thread.java:764) 

Вот мой интерфейс браузера:

    public interface IBrowse {
    void loadFirst(List<BrowseDTO> browseDTOList);
    void loadNext(List<BrowseDTO> browseDTOList);
}

my Просмотр активности:

    @Override
public void loadFirst(List<BrowseDTO> browseDTOList) {
    recycleViewAdapter.addAll(browseDTOList);
    if(currentPage <= TOTAL_PAGES) recycleViewAdapter.addLoadingFooter();
    else isLastPage = true;
}

мой ведущий просмотра:

 public static class BrowseTaskFirst extends AsyncTask<Integer,Void,List<BrowseDTO>>{
    IBrowse iBrowse;

    public BrowseTaskFirst(IBrowse iBrowse) {
        this.iBrowse = iBrowse;
    }
    @Override
    protected List<BrowseDTO> doInBackground(Integer... integers) {
        IBrowseService iBrowseService = APIClient.createService(IBrowseService.class, Token.getInstance());

        Call<List<BrowseDTO>> browseIssuesPage;
        browseIssuesPage = iBrowseService.getIssuesPaginated(integers[0]);
        try{

            return browseIssuesPage.execute().body();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(List<BrowseDTO> browseDTOS) {
        super.onPostExecute(browseDTOS);
        iBrowse.loadFirst(browseDTOS);
    }


}

мой просмотр DTO:

public class BrowseDTO {

IssueDTO issuesDTO;
private List<StockDTO> stockDTOlist;

public IssueDTO getIssuesDTO() {
    return issuesDTO;
}

public List<StockDTO> getStockDTOlist() {
    return stockDTOlist;
}

}

и, наконец, моя служба просмотра / контроллер

public interface IBrowseService {




    @GET("/Browse/{pageNumber}")
    Call<List<BrowseDTO>>getIssuesPaginated(
            @Path("pageNumber") int pageNumber);



}

при запуске приложения я вижу, что приложение обращается к моему приложению с весенней загрузкой, потому что оно получает данные с веб-сайта, но прерывается, когда я пытаюсь просмотреть список всех предметов

ОБНОВЛЕНИЕ

Вот ответ JSON:

    content: [
{
issueTitle: "52",
description: "When they arrive before the ruinous sweep, There shrieks are heard, there lamentations, moans, And blasphemies 'gainst the good Power in heaven.",
condition: "Average",
stockReferenceId: 49423,
availableQuantity: 0,
seriesNumber: 6,
price: 175.44,
publisher: "DC",
coverImage: "\Images\20.png"
},
{
issueTitle: "52",
description: "When they arrive before the ruinous sweep, There shrieks are heard, there lamentations, moans, And blasphemies 'gainst the good Power in heaven.",
condition: "Fine",
stockReferenceId: 24721,
availableQuantity: 1,
seriesNumber: 6,
price: 161.51,
publisher: "DC",
coverImage: "\Images\20.png"
},
{
issueTitle: "52",
description: "When they arrive before the ruinous sweep, There shrieks are heard, there lamentations, moans, And blasphemies 'gainst the good Power in heaven.",
condition: "Poor",
stockReferenceId: 74125,
availableQuantity: 0,
seriesNumber: 6,
price: 53.35,
publisher: "DC",
coverImage: "\Images\20.png"
},
{
issueTitle: "52",
description: "When they arrive before the ruinous sweep, There shrieks are heard, there lamentations, moans, And blasphemies 'gainst the good Power in heaven.",
condition: "Very Fine",
stockReferenceId: 19,
availableQuantity: 0,
seriesNumber: 6,
price: 43.06,
publisher: "DC",
coverImage: "\Images\20.png"
},
{
issueTitle: "52",
description: "Then I his alter'd hue perceiving, thus: "How may I speed, if thou yieldest to dread, Who still art wont to comfort me in doubt?"",
condition: "Average",
stockReferenceId: 49424,
availableQuantity: 0,
seriesNumber: 7,
price: 169.74,
publisher: "DC",
coverImage: "\Images\21.png"
},
{
issueTitle: "52",
description: "Then I his alter'd hue perceiving, thus: "How may I speed, if thou yieldest to dread, Who still art wont to comfort me in doubt?"",
condition: "Fine",
stockReferenceId: 24722,
availableQuantity: 0,
seriesNumber: 7,
price: 63.28,
publisher: "DC",
coverImage: "\Images\21.png"
},

1 Ответ

1 голос
/ 10 февраля 2020

Опубликованные вами модели не соответствуют json, добавленному вами в вашем вопросе. При использовании дооснащения без добавления каких-либо преобразователей модели java должны соответствовать самому json. Имена также важны.

Чтобы правильно проанализировать этот объект:

{
  issueTitle: "52",
  description: "When they arrive before the ruinous sweep, There shrieks are 
                heard, there lamentations, moans, And blasphemies 'gainst the 
                good Power in heaven.",
  condition: "Poor",
  stockReferenceId: 74125,
  availableQuantity: 0,
  seriesNumber: 6,
  price: 53.35,
  publisher: "DC",
  coverImage: "\Images\20.png"
}

Вам потребуется объект java с такой же структурой:

class Item {
  private String issueTitle;
  private String description;
  // and so on
}

Следующим шагом является анализ списка этих элементов. Поскольку root вашего json кажется другим объектом, нам нужно создать модель java, которая имеет такую ​​же структуру, как:

{
  content: [
      // ...
  ]
}

Этого можно достичь с помощью следующей модели:

class BrowseDTO {
  private List<Item> content;
}

И теперь вызов дооснащения должен возвращать этот класс:

public interface IBrowseService {
  @GET("/Browse/{pageNumber}")
  Call<BrowseDTO>getIssuesPaginated(
        @Path("pageNumber") int pageNumber);
}

Теперь он возвращает объект, который соответствует возвращенному json.

Ошибка, которую вы получаете прямо сейчас, говорит о том, что вы говорите о модернизации, что ожидаете массив - это List<BrowseDTO> - но вместо этого у вас есть объект - это элемент root в json (content ).

В этом примере я упоминал, что имена полей должны совпадать с именами из json. Хотя это не так, это не обязательно так. Поскольку вы используете Gson, один из самых простых способов изменить имя на другое - использовать аннотацию @SerializedName, которая изменит имя в json и позволит вам использовать любое поле имя, которое вы хотите, например:

class BrowseDTO {
  @SerializedName("content")
  private List<Item> items;
}

Хотя это не обязательно верно для всех приложений, в Android мы всегда добавляем эту аннотацию, даже если она имеет то же имя, что и поле, потому что сборки выпуска часто запутывается, и имя поля не будет точно соответствовать полю в json.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...