2016-08-14 5 views
3

, пожалуйста, помогите с Retrofit2. Я очень новичок в «Дооснащении». Я создаю простое серверное приложение. Приложение управляет списком Журналов: добавляет журнал в список в памяти и возвращает журнал по идентификатору. Существует Journal.java:Retrofit2: ClassCastException: java.util.ArrayList нельзя отбрасывать в retrofit2.Call

public class Journal { 
private AtomicInteger getNewId = new AtomicInteger(0); 
@SerializedName("id") 
@Expose 
private Integer id; 
@SerializedName("name") 
@Expose 
private String name; 

public Journal(String name) { 
    this.id = getNewId.incrementAndGet(); 
    this.name = name;} 

public Integer getId() {return id;} 
public String getName() {return name;} 
} 

Существует интерфейс контроллера:

public interface JournalController { 

@GET("journal") 
Call<List<Journal>> getJournalList(); 

@GET("journal/{id}") 
Call<Journal> getJournal(@Path("id") Integer id); 

@POST("journal") 
Call<Journal> addJournal(@Body Journal journal); 
} 

Это реализация интерфейса:

@Controller 
public class JournalControllerImpl implements JournalController { 
// An in-memory list that the controller uses to store the Journals 
private List<Journal> journals = new ArrayList<>(); 

@RequestMapping(value= "journal", method=RequestMethod.GET) 
public @ResponseBody Call<List<Journal>> getJournalList() { 
    return (Call<List<Journal>>) journals;} 

@RequestMapping(value= "journal/{id}", method= RequestMethod.GET) 
public @ResponseBody Call<Journal> getJournal(@Path("id") Integer id) { 
    Journal journal = journals.get(id); 
    return (Call<Journal>) journal;} 

@RequestMapping(value= "journal", method= RequestMethod.POST) 
public @ResponseBody Call<Journal> addJournal(@Body Journal journal) { 
    journals.add(journal); 
    return (Call<Journal>) journal; } 
} 

Применение начал succesesully. Консольный вывод во время запуска приложения:

Подключенные "{[/ журнал], методы = [GET]}" на общественном retrofit2.Call> main.JournalControllerImpl.getJournalList()

Подключенные «{[/ журнал ], методы = [POST]} "на публичный retrofit2.Call main.JournalControllerImpl.addJournal (main.Journal)

Отображено" {[/ journal {/ id}], methods = [GET]} "на общедоступный retrofit2 .Call main.JournalControllerImpl.getJournal (java.lang.Integer)

T han Я пытаюсь запустить URL http://localhost:8080/journal в браузере (или GET HttpRequest http://localhost:8080/journal). Существует ошибка в выходе приложения:

«... java.lang.ClassCastException: java.util.ArrayList не может быть приведен к retrofit2.Call ...»

Не могли бы вы догадаться, что это не так? Действительно ли проблемы с конверсией java.util.ArrayList для вызова? (Я судимый к CopyOnWriteArrayList, но это не помогает.

Спасибо заранее.

+0

'Journal' не' 'Вызов , который означает, что ваш бросок терпит неудачу. Вам нужно перенести журнал в 'Call' перед возвратом из любого метода. –

ответ

1

Call<T> класса дооснащения, что нужно только существовать на стороне клиента, это означает, что абстракция больше потенциальный вызов внешнего API.

Я не уверен, какие библиотеки вы используете для сервера, но вы не можете бросить совершенно несвязанные классы. (Такие, как ArrayList<T> к Call<List<T>>) Обычно библиотека будет обрабатывать сериализации для вас , поэтому на стороне сервера вы просто сразу вернете объект, который хотите отправить:

@RequestMapping(value= "journal", method=RequestMethod.GET) 
public @ResponseBody List<Journal> getJournalList() { 
    return journals;} 
+0

Спасибо, Kiskae, теперь он работает! – vzateychuk

1

Проблема была устранена, когда вызов был удален из JournalController (и класса реализации JournalControllerImpl). Теперь JournalController выглядит так:

public interface JournalController { 
String URL_PATH = "journal"; 

@GET(URL_PATH) 
List<Journal> getJournalList(); 

@GET(URL_PATH +"/{id}") 
Journal getJournal(@Path("id") Integer id); 

@POST(URL_PATH) 
Journal addJournal(@Body Journal journal); 
} 

И работает отлично.

1

Способ использования сервисного интерфейса (услуги) относится к сервису с обратным вызовом (onResponse, onFailure), реализующим детальную логическую необходимость, как указано ниже.

// Передача конструктора при создании JournalController journalService; // Возвращение списка журнала

Call<List<Journal>> call = journalService.getJournalList(); 
call.enqueue(new Callback<>() { 
    @Override 
    public void onResponse(Call<List<Journal>> call, Response<List<Journal>> 
     response) { 
     int statusCode = response.code(); 
     List<Journal> journal = response.body(); 

    } 

    @Override 
    public void onFailure(Call<Journal> call, Throwable t) { 
     // Log error here since request failed 
    } 
}); 

//Return a journal 

Call<Journal> call = journalService.getJournal(userId); 
call.enqueue(new Callback<Journal>() { 
    @Override 
    public void onResponse(Call<Journal> call, Response<Journal> response) { 
     int statusCode = response.code(); 
     Journal journal = response.body(); 
    } 

    @Override 
    public void onFailure(Call<Journal> call, Throwable t) { 
     // Log error here since request failed 
    } 
}); 

//Add journal 

Call<Journal> call = journalService.addJournal(new Journal("username"); 
call.enqueue(new Callback<Journal>() { 
    @Override 
    public void onResponse(Call<Journal> call, Response<Journal> response) { 
     int statusCode = response.code(); 
     Journal journal = response.body(); 
    } 

    @Override 
    public void onFailure(Call<Journal> call, Throwable t) { 
     // Log error here since request failed 
    } 
});