Retrofit2:ClassCastException:java.util.ArrayList无法转换为retrofit2.Call

3

请帮助使用Retrofit2。我在Retrofit方面非常新手。 我创建了一个简单的服务器应用程序。 该应用程序管理期刊列表:将期刊添加到内存中的列表中,并通过id返回期刊。 这是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;}
}

有一个控制器接口:

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

应用程序已成功启动。应用程序启动期间的控制台输出:

将"{[/journal],methods=[GET]}"映射到public retrofit2.Call> main.JournalControllerImpl.getJournalList()

将"{[/journal],methods=[POST]}"映射到public retrofit2.Call main.JournalControllerImpl.addJournal(main.Journal)

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

然后我尝试在浏览器上运行URL http://localhost:8080/journal(或GET HttpRequest http://localhost:8080/journal)。 应用程序输出中出现了错误:

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

您能猜出问题出在哪里吗? 是将java.util.ArrayList转换为Call时出现了问题吗?(我尝试过CopyOnWriteArrayList,但这没有帮助。)
提前致谢。

Journal 不是 Call<Journal>,这意味着您的转换失败了。在从任何方法返回之前,您需要将 Journal 包装在 Call 中。 - Eugen Pechanec
3个回答

1
使用服务接口(service)的方式是通过使用回调函数(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
  }
});

1

Call<T>是Retrofit类,只需要存在于客户端,它旨在抽象出对外部API的潜在调用。

我不确定您在服务器上使用哪种库,但您不能将完全不相关的类进行强制转换。(例如将ArrayList<T>转换为Call<List<T>>) 通常情况下,库会为您处理序列化,因此在服务器端,您只需直接返回要发送的对象即可:

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

1
问题已经解决,当从JournalController(和实现类JournalControllerImpl)中移除Call时。现在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);
}

并且完美运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接