Android、Mandrill 和 Parse.com:Java ClassCastException:HashMap 无法转换为类

Posted

技术标签:

【中文标题】Android、Mandrill 和 Parse.com:Java ClassCastException:HashMap 无法转换为类【英文标题】:Android, Mandrill and Parse.com: Java ClassCastException: HashMap cannot be cast to a class 【发布时间】:2014-09-14 01:26:43 【问题描述】:

我不知道问题是否源于这么久,所以无论如何我都会告诉你。根据 Parse 和 Mandrill API 文档,我有一个存储为 Parse Cloud Code 的函数,它检索用户的预定电子邮件列表。然而,根据他们的文档,从 Mandrill 返回的对象是一个包含字符串键值对的结构数组。您可以在此处查看相关文档:https://mandrillapp.com/api/docs/messages.JSON.html#method=list-scheduled

Parse Cloud Code 只能在 javascript 中,所以返回的数组是如何解释的,我不确定。无论哪种方式,我都让云函数将返回的数组直接返回给在我的 android 应用程序中调用它的 Java 方法。我以为它会以 JSONArray 的形式出现,但似乎并非如此。我的编辑器 Android Studio 坚持返回类型为ArrayList<ScheduledEmail>,并且不允许我使用任何其他参数类型,因此我将其设置为该类型。 (ScheduledEmail 是我在 Java 中创建的类,用于匹配从 Mandrill 返回的结构中包含的元素,用于此方法。这是我出错的部分吗?如何将返回数组中的这些结构转换为与 Java 兼容的键-值对?)但是,当我尝试访问数组中包含的对象时,我收到此错误:

    java.lang.ClassCastException: java.util.HashMap cannot be cast to com.****.******.ScheduledEmail

似乎没有使用过 HashMap。我错过了什么?在将返回的数组发送回 Java 方法之前,我是否应该先对返回的数组做一些事情? Mandrill 是否返回了 HashMap?如果是这样,为什么它会被解释为我打算匹配的 Java 类?

有问题的Java方法的相关部分如下:

HashMap<String, Object> params = new HashMap<String, Object>();
params.put("recipient", "koolstr@gmail.com");
ParseCloud.callFunctionInBackground("listScheduledEmails", params, new FunctionCallback<ArrayList<ScheduledEmail>>() 
    public void done(ArrayList<ScheduledEmail> schedEmailsFromJS, ParseException e) 
        if (e == null) 
            for (int i=0; i < schedEmailsFromJS.size(); i++) 

                //This is the line which produces the error
                Log.d("sEmail", schedEmailsFromJS.get(i).get_id());
            
        
    
);

这是 Parse Cloud Code Javascript 函数,我在其中从 Mandrill 检索预定电子邮件列表:

Parse.Cloud.define("listScheduledEmails", function(request, response) 
Parse.Cloud.httpRequest(
    method: 'POST',
    headers: 
        'Content-Type': 'application/json;charset=utf-8'
    ,
    url: "https://mandrillapp.com/api/1.0/messages/list-scheduled.json",

    body: 
        key: "***************",
        to: request.params.recipient
    ,
    success: function(httpResponse) 
        console.log("The scheduled emails have been successfully retrieved.");
        console.log(httpResponse.data);
        response.success(httpResponse.data);        
        console.log("Returned the list successfully.");
    ,
    error: function(httpResponse) 
        console.error('Request failed with response code ' + httpResponse.status);
        response.error("Failed to retrieve messages.");
    
);
);

我们将不胜感激任何帮助、想法、澄清或批评。我在这个问题上被困了半天,我似乎无法解决它。我不知道我哪里错了。

【问题讨论】:

哪个 Java 语句抛出异常? 正如我在发布的代码中作为评论所写,这是产生错误的行:Log.d("sEmail", schedEmailsFromJS.get(i).get_id());。我尝试将数组用于什么并不重要。我什至试过这个,它产生了同样的错误:ScheduledEmail test = schedEmailsFromJS.get(0); 【参考方案1】:

你首先需要弄清楚传递给FunctionCallback的是什么类型:

ParseCloud.callFunctionInBackground("listScheduledEmails", params, new FunctionCallback<Object>() 
    public void done(Object o, ParseException e) 
        if (e == null) 
            Log.i("Tag", "Return type = " + o.getClass().getName());
        
    
);

完成此操作后,更改您的FunctionCallback 以正确处理返回的类型,并在需要时将其映射到您自己的 bean 类型。我假设返回的类型将是某种哈希映射列表。

如果确实如此,您可以将您的实现更改为类似这样的内容,以获取您的 ScheduledEmail 对象列表:

ParseCloud.callFunctionInBackground("listScheduledEmails", params, new FunctionCallback<List<Map>>() 
    public void done(List<Map> list, ParseException e) 
        if (e == null) 
            ArrayList<ScheduledEmail> scheduledEmails = new ArrayList<>();

            for(Map<String, ?> data : list) 
                ScheduledEmail scheduledEmail = new ScheduledEmail();
                scheduledEmail.set_id(data.get("_id"));
                // ... extract rest of data

                scheduledEmails.add(scheduledEmail);
            
        
    
);

【讨论】:

感谢您的天才方法。日志说对象类型是一个ArrayList,里面的对象是HashMaps。那么现在应该在我的代码中进行哪些更改才能正确地将这个 ArrayList 解析为可用数据? 非常感谢!有效!我只需将其设为 ArrayList 而不是 List,以便它可以 Parcelable,以便我可以将其发送到另一个 Activity。另外,我忘了提到当你写Log.i("Return type = " + o.getClass().getName());时,你忘了包含String标签。 明白了。更正了我的答案。

以上是关于Android、Mandrill 和 Parse.com:Java ClassCastException:HashMap 无法转换为类的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 Parse Cloud Code 和 Mandrill 发送电子邮件

无法让合并标签工作 - Mandrill/Parse

Mandrill Handlebar 模板无法正确渲染/与 Parse.com 对象合并

将 Java 字符串数组或 JSON 字符串转换为 Javascript 数组(Parse.com Cloud Code 和 Mandrill)

在 iOS 7 中,如何使用 Mandrill 向我的 Parse 驱动的应用程序管理员发送一封简单的电子邮件?

Mandrill 解析 facebook 编码问题