Retrofit2: ClassCastException: java.util.ArrayList cannot be cast to retrofit2.Call

允我心安 提交于 2019-12-12 16:33:27

问题


please help with Retrofit2. I'm very new in Retrofit. I create simple server application. The application manage list of Journals: add Journal in the in-memory list and return Journal by id. There is an Journal.java:

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;}
}

There is an controller interface:

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);
}

This is interface implementation:

@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; }
}

The application started succesesully. Console output during application's startup:

Mapped "{[/journal],methods=[GET]}" onto public retrofit2.Call> main.JournalControllerImpl.getJournalList()

Mapped "{[/journal],methods=[POST]}" onto public retrofit2.Call main.JournalControllerImpl.addJournal(main.Journal)

Mapped "{[/journal{/id}],methods=[GET]}" onto public retrofit2.Call main.JournalControllerImpl.getJournal(java.lang.Integer)

Than I try to run URL http://localhost:8080/journal on browser (or GET HttpRequest http://localhost:8080/journal). There is an error in application output:

"... java.lang.ClassCastException: java.util.ArrayList cannot be cast to retrofit2.Call..."

Could you guess what is wrong? Is it really problems with conversion java.util.ArrayList to Call ? (I've tryed to CopyOnWriteArrayList but this doesn't help.

Thank you in advance.


回答1:


Call<T> is a Retrofit class that only needs to exist on the clientside, it is meant to be an abstraction over a potential call to an external API.

I'm not sure what kind of library you are using for the server but you cannot cast completely unrelated classes. (Such as ArrayList<T> to Call<List<T>>) Usually the library will handle serialization for you, so on the server side you would just directly return the object that you want to send:

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



回答2:


The problem has been resolved when the Call been removed from the JournalController (and implementation class JournalControllerImpl). Now JournalController looks like:

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);
}

And works perfectly.




回答3:


The way to use the service interface (service) is to the service with a callback (onResponse, onFailure)implement the detail the logic need as highlighted below.

//Pass in a constructor upon creating JournalController journalService; //Return journal list

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
  }
});


来源:https://stackoverflow.com/questions/38940610/retrofit2-classcastexception-java-util-arraylist-cannot-be-cast-to-retrofit2-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!