【问题标题】:Retrofit2: ClassCastException: java.util.ArrayList cannot be cast to retrofit2.CallRetrofit2:ClassCastException:java.util.ArrayList 无法转换为 retrofit2.Call
【发布时间】:2016-12-20 19:18:39
【问题描述】:

请帮助改造2。我是 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 无法转换为 retrofit2.Call..."

你能猜出哪里不对吗? 将 java.util.ArrayList 转换为 Call 真的有问题吗? (我尝试过 CopyOnWriteArrayList 但这没有帮助。

提前谢谢你。

【问题讨论】:

  • Journal 不是 Call&lt;Journal&gt;,这意味着您的演员阵容失败。在从任何方法返回之前,您需要将 Journal 包装在 Call 中。

标签: java call server-side classcastexception retrofit2


【解决方案1】:

使用服务接口(service)的方式是通过回调(onResponse, onFailure)对服务实现如下高亮显示的逻辑需要的细节。

//创建时传入构造函数 JournalController 日志服务; //返回期刊列表

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

【讨论】:

    【解决方案2】:

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

    而且效果很好。

    【讨论】:

      【解决方案3】:

      Call&lt;T&gt; 是一个只需要存在于客户端的 Retrofit 类,它是对潜在调用外部 API 的抽象。

      我不确定您为服务器使用的是哪种库,但您不能强制转换完全不相关的类。 (如ArrayList&lt;T&gt;Call&lt;List&lt;T&gt;&gt;) 通常库会为您处理序列化,因此在服务器端您只需直接返回您要发送的对象:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-14
        • 2020-06-15
        • 2017-08-24
        • 1970-01-01
        • 2016-11-21
        相关资源
        最近更新 更多